{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "7edbe9a4",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1. Preprocess documents¶\n",
    "# Fetch documents to use in our RAG system. We will use three of the most recent pages from Lilian Weng's excellent blog. We'll start by fetching the content of the pages using WebBaseLoader utility:\n",
    "from langchain_community.document_loaders import WebBaseLoader\n",
    "\n",
    "urls = [\n",
    "    \"https://lilianweng.github.io/posts/2024-11-28-reward-hacking/\",\n",
    "    \"https://lilianweng.github.io/posts/2024-07-07-hallucination/\",\n",
    "    \"https://lilianweng.github.io/posts/2024-04-12-diffusion-video/\",\n",
    "]\n",
    "\n",
    "docs = [WebBaseLoader(url).load() for url in urls]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "365e70bd",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1. Preprocess documents¶\n",
    "# Fetch documents to use in our RAG system. We will use three of the most recent pages from Lilian Weng's excellent blog. We'll start by fetching the content of the pages using WebBaseLoader utility:\n",
    "from langchain_community.document_loaders import WebBaseLoader\n",
    "\n",
    "urls = [\n",
    "    \"https://lilianweng.github.io/posts/2024-11-28-reward-hacking/\",\n",
    "    \"https://lilianweng.github.io/posts/2024-07-07-hallucination/\",\n",
    "    \"https://lilianweng.github.io/posts/2024-04-12-diffusion-video/\",\n",
    "]\n",
    "\n",
    "docs = [WebBaseLoader(url).load() for url in urls]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "94131dc1",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"Reward Hacking in Reinforcement Learning | Lil'Log\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\nLil'Log\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n|\\n\\n\\n\\n\\n\\n\\nPosts\\n\\n\\n\\n\\nArchive\\n\\n\\n\\n\\nSearch\\n\\n\\n\\n\\nTags\\n\\n\\n\\n\\nFAQ\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n      Reward Hacking in Reinforcement Learning\\n    \\nDate: November 28, 2024  |  Estimated Reading Time: 37 min  |  Author: Lilian Weng\\n\\n\\n \\n\\n\\nTable of Contents\\n\\n\\n\\nBackground\\n\\nReward Function in RL\\n\\nSpurious Correlation\\n\\n\\nLet’s Define Reward Hacking\\n\\nList of Examples\\n\\nReward hacking examples in RL tasks\\n\\nReward hacking examples in LLM tasks\\n\\nReward hacking examples in real life\\n\\n\\nWhy does Reward Hacking Exist?\\n\\n\\nHacking RL Environment\\n\\nHacking RLHF of LLMs\\n\\nHacking the Training Process\\n\\nHacking the Evaluator\\n\\nIn-Context Reward Hacking\\n\\n\\nGeneralization of Hacking Skills\\n\\nPeek into Mitigations\\n\\nRL Algorithm Improvement\\n\\nDetecting Reward Hacking\\n\\nData Analysis of RLHF\\n\\n\\nCitation\\n\\nReferences\\n\\n\\n\\n\\n\\nReward hacking occurs when a reinforcement learning (RL) agent exploits flaws or ambiguities in the reward function to ac\""
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "docs[0][0].page_content.strip()[:1000]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "561d468e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Split the fetched documents into smaller chunks for indexing into our vectorstore:\n",
    "from langchain_text_splitters import RecursiveCharacterTextSplitter\n",
    "docs_list = [item for sublist in docs for item in sublist]\n",
    "text_splitter = RecursiveCharacterTextSplitter.from_tiktoken_encoder(\n",
    "    chunk_size=100, chunk_overlap=50\n",
    ")\n",
    "doc_splits = text_splitter.split_documents(docs_list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "8ec377b8",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['0f209f61-50ff-4565-999b-3c43dc32ddc8',\n",
       " 'b1bc0a11-9fce-469d-a514-51cf5542be70',\n",
       " '8117573a-8a29-40d2-9d98-f5c4df7574f1',\n",
       " 'be2eff0f-e717-4e33-a9c0-6c13da9352f5',\n",
       " 'bdb7a5de-6c33-4516-97e2-0af44cb9d870',\n",
       " '7071b26e-000a-4224-80a0-d973983f7a75',\n",
       " '53e4a66a-2fe9-4bc9-a9ae-706ffd5a8c99',\n",
       " 'cc62e139-daca-47f6-91f7-d46072b97875',\n",
       " '3a4aae38-475f-4924-966f-db1fd1f29b0c',\n",
       " '4e597df1-58b2-4f48-861f-ba7717772294',\n",
       " 'c64317a9-3dd9-49c1-8121-83a859fbca8d',\n",
       " '780bb4ff-2c00-40fd-8854-8c269292951c',\n",
       " '58b6f97d-b568-43da-aa3b-c0b0212e7380',\n",
       " '7b9cc19c-0c73-40ef-935b-8c835ee3bd0a',\n",
       " 'a61ec313-55ee-48d1-bf4b-6aa1959aef80',\n",
       " '775b3076-1a8b-468b-b568-83ccde2a7e6e',\n",
       " 'b0fddf75-0cb0-4d41-907e-b13cc25a01b4',\n",
       " '0129ed13-da22-46b6-968f-1ad98c3e1107',\n",
       " '9e9ef291-7564-4b9f-a0bc-57809e7c34f0',\n",
       " '9704d463-441d-42cf-8383-fb2bb57dd402',\n",
       " '9b75072e-17d0-4f0a-814f-a229ccd6fb14',\n",
       " 'e7604e27-6d9c-49f0-a358-82e16e40457c',\n",
       " '0aa68a31-67a1-43ad-bbf8-5afa506fee04',\n",
       " '22c5eafb-4da1-46c9-9c06-db87215bde60',\n",
       " 'cbe814d4-7e6c-4259-a510-2e4d8d8909a3',\n",
       " '3c87c2d8-ad6e-4bb7-a9e7-1cb797015bd2',\n",
       " '109f550d-24ff-42e9-bfc6-16c6414f9cf7',\n",
       " '7417788f-8b2d-4071-a059-02c94d4f8083',\n",
       " '8ff936a1-4e03-499a-b3c2-046bf4acd482',\n",
       " '1bafaace-51fb-4840-94ef-40ed21113107',\n",
       " '6db16931-a5d1-4518-a0fc-2e2f482b0962',\n",
       " 'f129b882-5485-4f07-bc45-fc50ec623a92',\n",
       " '47047f45-9baa-4aaf-bfd7-d0e3df5a27a3',\n",
       " '212a5116-7d37-49d9-9ea6-1f6318c5ad43',\n",
       " '1f7230ec-7484-4dfc-8b17-6d1b70d211b1',\n",
       " '60f82cf9-4e4c-4acd-900d-57a28dd699aa',\n",
       " 'fdb2db71-1082-43c8-a76d-46a93238322c',\n",
       " '3644066f-c32a-4634-b9d2-640a620aed51',\n",
       " '081751d8-9945-4ae8-8f91-91b93b5bb142',\n",
       " '8d82c5cb-bea9-4936-ae5f-b59729a9e4f9',\n",
       " 'a0d5fcbf-f526-4ae4-8efb-43405e53f863',\n",
       " 'fff6161b-fca3-40f2-8919-d4de86ca31c6',\n",
       " '731c37bd-7f33-48b7-9c86-d8949d616f32',\n",
       " '50f049c6-f74b-418d-bb55-378b8f0ff6ce',\n",
       " 'af5c219a-a34b-4934-83ca-532deb20d430',\n",
       " 'b007e685-1b00-40b1-97ee-de73d5c2b6c4',\n",
       " '2355847a-062e-431e-81eb-fc678bf30ac0',\n",
       " '3f126e9b-460e-4e26-a5b4-278b2f5e62d6',\n",
       " '12940ace-b9c7-4c5e-b919-c8d627536049',\n",
       " 'd978012e-a0c8-496f-a670-ddb1f69e078b',\n",
       " '7ab79cad-cf97-43e9-a31a-c471b6898422',\n",
       " '3f5d195b-0070-4e44-bd9c-ba68e7a0a064',\n",
       " '3cc7a48d-4c4f-47b7-b6ec-c2d560cee468',\n",
       " '79a32863-b1dc-4965-b9f2-eb067373f1ea',\n",
       " '1ee34aca-6b48-465a-b369-003c115e6ccd',\n",
       " 'ba6b8983-dbee-4ecf-b570-8c46ad2df0a0',\n",
       " '82488b97-7a59-4bff-b618-b0981cfab2e3',\n",
       " 'd2a0db9f-365b-461d-a8b4-29a361aef0de',\n",
       " 'f93f2769-3a34-4b79-945c-7ab63c90054d',\n",
       " '40b2c826-a395-45df-9495-2ab9baa192ab',\n",
       " 'e0de569d-c6da-49f0-9355-79feaa6543e0',\n",
       " '9940ba06-0d7d-4e80-8688-00fe4915820c',\n",
       " 'f25cb291-8d5c-4836-8c26-2dda1e3106b8',\n",
       " '65992dbf-2ca3-4ee8-a050-35411a213197',\n",
       " '922ef7f1-96ea-40fa-b097-c93d87be5aaf',\n",
       " 'd00cfc20-d584-4fa6-a98f-6a9972c3f50c',\n",
       " 'a77eebde-5354-49f5-9819-32a4973de478',\n",
       " '22d41fe0-d778-4138-bc88-3bbbfccd4064',\n",
       " '14be132d-5594-430b-ba18-33cddae09223',\n",
       " '3e22d2d0-17b1-42a7-be34-f4d41ef1d759',\n",
       " '5aeb46eb-507b-4def-8054-d4137e25268c',\n",
       " '9717085d-5826-4499-9eef-31b41b8424b9',\n",
       " '3fb3d749-15ef-4aac-b81a-4deb7f84cf56',\n",
       " '2854f61f-53f4-4692-a235-ba1ee631dd38',\n",
       " '1a67be54-cd52-448e-ada5-67667737b7e0',\n",
       " '991bfb33-9034-491c-b0f9-316b5541c9ea',\n",
       " 'e4f51cfd-4796-4406-965d-776b67b57541',\n",
       " 'b9fcb488-403d-4c50-9a7c-f88782bd06fd',\n",
       " 'f51311c4-3eee-414d-b36c-1e20c91eb66a',\n",
       " '7cefdc9f-172b-47e3-bb65-2d48a74df528',\n",
       " 'c064c20b-cda6-4d93-90a1-09fe9a1b06b3',\n",
       " 'bcec10c2-e32a-49d9-af51-8de36a67f0d5',\n",
       " '9d3a502c-c301-4e0d-adf9-c93c9f8a8728',\n",
       " 'c2a97a41-caa6-4c8b-9b98-5faa176c3974',\n",
       " 'd386a466-75f4-439f-9853-a5ecd1cfeba5',\n",
       " '31cd64d7-2233-4123-ac8d-5fadbb0b3afc',\n",
       " 'f70e6f42-82ec-4194-8132-cbdee6e9f3ec',\n",
       " '9dec9e14-1de1-447c-8eb3-94ffe7cef313',\n",
       " 'cd983eb2-9b11-453c-9480-7b563f0ecb70',\n",
       " '21b7aa0c-2c56-4c04-9b38-b92c0adaf279',\n",
       " '6a269158-61c2-4ae1-ba2e-8d06730d6f3a',\n",
       " '6dfd1bde-7b29-40c5-9d6b-1068bf038c23',\n",
       " '81ab5464-6e10-4bd2-bb8b-32787cdf1341',\n",
       " 'fce50bd5-85ee-4f39-8927-abf573972f81',\n",
       " 'a37088ec-a2a5-4714-a05c-5db76d42941d',\n",
       " '83e20452-6cac-4588-938c-7dca35ac2ce5',\n",
       " '9e993458-6610-4610-b357-128aad8ad1bc',\n",
       " '418939e9-ac7a-4e03-a4e1-f466b952d77a',\n",
       " 'a22cea00-c446-4721-9f77-1affd9750852',\n",
       " '7d207a99-a03e-4269-8cfa-504bb169126a',\n",
       " '6e6adb40-5819-43ee-8720-c00a79fee8da',\n",
       " '0f49e541-1af2-4dbd-81df-d4352bbfc24f',\n",
       " '7bf46744-54d6-4860-87ff-ba38374fe00f',\n",
       " 'fb0d0496-374d-4fe7-9e1d-07738994b92e',\n",
       " 'cff0640d-4ed5-43ac-a0e8-a30a7342fba6',\n",
       " '1e0e9b5b-73e3-43a6-9aad-c6b92342eb02',\n",
       " '494d65ed-ec1d-40af-8f7f-20a900790dc3',\n",
       " '99700456-4b35-4229-9331-d446ffec9702',\n",
       " 'c42c793f-7489-40d2-9481-46a89963d91f',\n",
       " '3d9938e5-fc26-458d-acdf-cd30331cd581',\n",
       " '4e6ba5b4-9940-4dee-b420-3e52ce2696aa',\n",
       " '0c6cc080-716b-4fbd-b03b-97477b5cb77b',\n",
       " '8e2d39a1-5f6f-47b8-a3f3-052c111a79c0',\n",
       " '2223ed02-6d9b-4d0a-a77d-d8ccdfdfd0e4',\n",
       " '28ca0694-4850-491c-ac59-73a64a3e94a9',\n",
       " 'fecb84a8-45ea-46ac-b38a-967c5d210e46',\n",
       " '6a17ed4f-43ff-4a75-aee0-557d0ca657fa',\n",
       " '83aac130-e411-4479-ba20-fc12e9af8302',\n",
       " '8943ea76-514f-4374-8bb4-1b1f49b2781c',\n",
       " '110e1799-d6c2-4dd3-9e89-cc96b81da614',\n",
       " '1c5a0b33-6150-4218-abb2-b4cd124eee73',\n",
       " '031684b0-0b5d-43af-a552-53d0155e4b19',\n",
       " 'b83acd7b-35f0-432b-a0dd-f22afede4270',\n",
       " '0df866b0-59fe-4b38-835c-26187e75d60f',\n",
       " 'd9c0cbc2-516a-4d32-bc68-ab800494d234',\n",
       " 'ff2a8b61-dc40-4032-9340-fea6d7250716',\n",
       " '2145a84b-0886-4e75-a87b-ce9f2529d4a9',\n",
       " '06665c72-62e3-4b1a-ab0a-63f354b03bd1',\n",
       " '6f0c3d4c-818c-41a4-b0ce-13a71794d29e',\n",
       " 'b164a8a2-6635-436d-92be-11e4197b3651',\n",
       " 'eb63b303-1913-4882-843f-e3b6fac08402',\n",
       " '2475bd2e-c6c8-41ce-aa3e-538ebc4854f2',\n",
       " 'd42ebaad-d762-4505-a3ab-6132d56a2096',\n",
       " 'a71e875f-5864-41a8-a468-dff9eb5623f4',\n",
       " '41eaf0b1-0d85-481e-8d64-b160f3401b50',\n",
       " '2a373e33-e3fc-42e3-80eb-ba1421543359',\n",
       " 'e7fcff1c-43ec-46a4-976a-8e63edab5136',\n",
       " 'fd14ed09-c654-49f4-9531-2c4d580b0949',\n",
       " '95b15fff-95e2-49a3-a19d-aaf5f4265a5c',\n",
       " '7080f8eb-7353-4ba4-bd81-c0157a88bc2a',\n",
       " '563f5e7d-2c72-4ca5-8909-6a13ddb138ec',\n",
       " '22ef7059-6509-4dbb-9bbe-f69530d158d0',\n",
       " 'f2c01f57-657b-4083-88e8-10883e43573d',\n",
       " '3aa9e8d2-7139-46b0-baa7-3c454b374695',\n",
       " '47e470f5-8229-4b04-9f6e-fa602ead97e9',\n",
       " 'b7917f4f-0754-479f-9373-55c5944585c4',\n",
       " '825d49a0-20ed-48d5-99a7-7a158f9b2cf0',\n",
       " '78d1a328-e482-4821-a9bc-07d82dffb7bf',\n",
       " 'd8cf174d-8a8d-46d1-9c78-2e3ee0159fcc',\n",
       " '43ac333b-0add-4ecd-9bf8-d0ba71da9550',\n",
       " '05e7ef0c-b483-45ca-839c-07b4a477c973',\n",
       " '3ce380ea-2370-4e16-97da-f37f657c6176',\n",
       " '4cff14c7-1422-4012-8636-e40889a235f1',\n",
       " '543dc21f-b3e9-40d1-8d5b-0e71cdf0859a',\n",
       " '9c4b31b6-61a2-4df0-b3ef-771598122317',\n",
       " '8c8223a8-ded5-496e-83c2-53347bc49eca',\n",
       " 'd59beb47-c223-4ef8-9691-0f7b09b35a38',\n",
       " 'be685ece-fb6b-4df2-afa7-77654b785dc4',\n",
       " 'e54a078c-3e03-447d-8c70-49b77b7866fe',\n",
       " 'c774ec9e-a21b-4d91-8546-f6156da56479',\n",
       " 'c2778b48-7241-46ef-ae6e-cfa1d670a9c6',\n",
       " 'c317a215-ee5b-450a-8bf8-ebc6ad0bd71b',\n",
       " 'bf3fae25-a6eb-4f02-90c3-0c2853495be1',\n",
       " '3aff711b-fc21-40e5-ab2c-fbbb6e78717d',\n",
       " '9206b19b-ded1-421b-aadd-f72ada92f032',\n",
       " '32f83f30-d280-406d-968b-f60d6cecfe57',\n",
       " 'edb0ebb9-e1ff-49ab-8c5d-755d5774925b',\n",
       " '5bee284d-51bb-48f7-9972-ea788f7fed4a',\n",
       " 'ee644572-dd51-4680-ae69-617f5955057f',\n",
       " '335550f1-06f6-4ad7-9b40-7398bc3e4f96',\n",
       " 'a652191a-f10e-4dc8-b0e7-29223b141e8e',\n",
       " 'bedcabb4-1195-4864-a7c3-1389b30565db',\n",
       " '50f10909-afd0-46fd-b805-0da35c3914a5',\n",
       " '78bcb0ae-d728-48de-b7a9-181f44a2435e',\n",
       " '33b89d54-dece-470e-b31f-9077f5235312',\n",
       " 'd93207b9-3788-406d-8d4f-489605cd8b52',\n",
       " 'afa28859-29c7-43a6-9fe3-d0415c646809',\n",
       " 'cf804292-f29c-441a-9f51-2506362b98e8',\n",
       " '4c9ebcd1-1024-49f4-b43a-31a56e47bf6c',\n",
       " '1f64496e-3c9d-4d5a-9c4d-2e37fb63a507',\n",
       " 'bcd42737-92cb-4b29-8a81-9fbd51dc6d19',\n",
       " '143f1cd0-efa9-41a1-9ce2-1aef0c1b840a',\n",
       " 'fcd09c68-a2ea-4f96-aeb1-70fa80959a76',\n",
       " '9bee72d2-265b-4639-b73c-2dfa92aebb0f',\n",
       " '0fd6bbf3-d63a-4cbb-a073-f0681676b766',\n",
       " 'cd0f08a9-8c4e-4955-996f-d4e7b640494c',\n",
       " '58de99fd-d6f4-4599-ade9-bd439353c9eb',\n",
       " '461c2b25-cbdd-4a48-a82f-ff898d05e379',\n",
       " '07e3ecc0-4ac4-455e-9bf7-279882686580',\n",
       " '419ec42e-2ee3-43f3-8fa2-87a65c1dc417',\n",
       " 'f9f2a3f5-294b-4b37-a7b9-df4ce3316538',\n",
       " '21f3aeff-7ed5-4a76-8b92-596721126fed',\n",
       " 'f3fa0aa3-a1de-48ce-a2f4-bb1ccf839b28',\n",
       " '76072364-9bef-4001-9ff8-d21ee3174e8a',\n",
       " '292c1d0e-e224-41cf-9cba-bd554ce28d9e',\n",
       " '7ac0b4c7-1fbd-45ca-b5e0-ab05fc2baee3',\n",
       " '1869b0b0-a8a2-443e-9537-72bc10ca3f94',\n",
       " '2284c82b-add7-45ea-a7db-830cbb7aa055',\n",
       " '9d2478f0-627d-49c7-a340-008a2bf0e521',\n",
       " '50580bba-c55a-46d7-85f2-6724f0abbc95',\n",
       " 'e675ccc3-d30b-44d4-8b58-fe00c2b06d90',\n",
       " '7c5af97c-fa64-4b4d-888e-5f51eeb6c594',\n",
       " '89208e6e-4275-41fe-9a8b-75797ba24f94',\n",
       " 'ad29267f-a127-4d80-82e7-cf193694e224',\n",
       " '0e8b8cb5-ff85-444f-9786-40bcb7720ea1',\n",
       " '4fc4e2a1-6594-47a8-8222-f99d0fa9afea',\n",
       " 'ec7832bb-4c6c-4584-a666-af5ef29dfe69',\n",
       " 'd812066a-5053-493a-874e-c3557972a94b',\n",
       " '42afc446-b4b9-4cda-8406-6352979a916a',\n",
       " '1276cc82-6f00-4752-a464-846891b28cbb',\n",
       " '1be4ca9c-9065-40f1-a472-5ffb98e47c6f',\n",
       " 'adad3253-71e2-416d-8e5d-d4cccc662099',\n",
       " '53a18996-881b-41e9-a8c4-14c102e450fd',\n",
       " '7526404f-68ed-497e-b1da-4d53d028be27',\n",
       " 'fd027761-e966-43ca-9d0e-9a03063bec53',\n",
       " '9cfc10f4-6b47-434a-b676-171908a9e223',\n",
       " 'dc257d81-e36f-48c5-833a-6d3b07ae5ff1',\n",
       " '492db6ab-f0ef-4464-a32d-ea7d279ace09',\n",
       " '21f68892-36ff-4f83-be7f-ddb5c7bdb0cd',\n",
       " '5bb2f3d9-dc16-4995-86ac-0375ed39a221',\n",
       " '7e5efff0-2582-4983-979d-78915ad6a261',\n",
       " '005fb505-1aef-4172-8959-0d57f8606ff8',\n",
       " 'd4dd53c4-06b6-4d71-a7e1-d48dc7f08a94',\n",
       " '6bd0af4c-4ba2-4409-b8c4-a9fcd8490001',\n",
       " 'a46ee522-f004-40eb-b83b-711a8607775a',\n",
       " '6f1e928e-a21a-4e6b-9f9a-2d0d64c92ab5',\n",
       " 'ed20ea7c-c503-43c7-becd-c65c0fd6c628',\n",
       " '124ae5c7-3272-445f-84e1-5354fc40b7b1',\n",
       " 'b53bdd19-ac62-4459-aced-3d76d8963e90',\n",
       " '21fad953-67c9-419e-ba29-1b0bfdd2be55',\n",
       " 'edf822a9-f842-40ba-a48c-eee3c7d718ce',\n",
       " 'de0a7d70-20a8-4683-8308-82a1d12c55f9',\n",
       " 'ac7bc096-686d-45d8-8bb0-50c33dfe6750',\n",
       " '48b2ef6d-4587-4a7f-b495-623e354b647b',\n",
       " 'ff1ddcaf-fef8-456a-ad49-01f229d9d4cc',\n",
       " 'cac99a5f-c6d1-46f3-84f5-68378daf73cd',\n",
       " '1ec1ee7c-b485-45f0-a678-aacc60bfb3f0',\n",
       " '02c636fc-c516-4835-ba94-9ecd5dcdf4a5',\n",
       " '2d5a3813-ab97-4dc0-a2a5-f23ff552fa90',\n",
       " 'fd7b3020-e44e-4521-9453-18151c1735fd',\n",
       " '0d2168d4-5c2a-4d29-abc5-e8fa6631ce33',\n",
       " '73f4f645-8b9a-4d94-800d-8610f38d4258',\n",
       " '87aa51de-f560-4e02-89c6-c30ee4a955e9',\n",
       " 'd9259923-7c95-4c63-b413-dc26eb4b07e0',\n",
       " '6e59a063-6d9b-4477-aec9-8b7267045bfe',\n",
       " '87792683-287e-4ffd-8d82-ce53cd11d992',\n",
       " 'a34a1d6e-7965-42a6-87cc-b3cceb792520',\n",
       " 'a3882dee-72cc-40d0-83fe-e53d3ce095bc',\n",
       " 'f3e5630c-0840-4e6a-97c2-1bb9681560c2',\n",
       " '1af7425a-77e7-404e-ab99-ac61e027d8cc',\n",
       " 'c6047fbd-3693-4f3e-9eb6-11d24f7e04b6',\n",
       " '8652fc3e-62b9-4332-8f25-e6e765f2f88d',\n",
       " '4cbb8205-92b2-49da-a04c-3756c5b9f5aa',\n",
       " 'b7c3f25c-7798-4195-8c27-17ca21329979',\n",
       " '38cd4241-3332-4b07-98e1-a66e9b5ae1ed',\n",
       " '904de07a-aaeb-44d4-b336-9c1f5f561aa1',\n",
       " 'bd32810d-84a7-49ae-b384-8b9879b81865',\n",
       " 'dc68dba8-5b29-442f-81b2-e72815498541',\n",
       " '98aff1d0-d4ec-41f7-9a81-ce13a000375e',\n",
       " '686d26fb-879b-4261-8562-8009889a2dad',\n",
       " '386cef0a-2753-4306-96fc-037901302896',\n",
       " '646e9204-9d27-4c09-8816-2323199f6eb8',\n",
       " '913ec81d-67ba-4228-8d38-f138bb683d4f',\n",
       " 'dd2ff318-6204-4814-b348-f87c2729078d',\n",
       " '76ddac43-4a3e-4682-86eb-48f389d1abc0',\n",
       " 'af19cdde-0d55-4270-83e8-64f620b7c466',\n",
       " '9ac8dd39-bf8d-4a12-b215-86c0078e16a6',\n",
       " 'b2c3a9ca-69a1-4e76-b761-2b81a01130ed',\n",
       " '9ab699ff-6942-48a4-bd00-962496189ad0',\n",
       " '746f8bab-0840-4b35-934d-6964ae5a2380',\n",
       " 'f73d67a2-9f92-4d34-90c9-e7041b169a1c',\n",
       " 'a47070f4-1fb3-4030-bf51-bbf314be4f86',\n",
       " 'ceff0770-350c-40ac-a254-794198dc9b3c',\n",
       " '860af614-175b-4cd9-b77c-6f8b849d4d02',\n",
       " '4e16cf39-3077-4661-aa2b-1e4fd8777250',\n",
       " 'c135d8a2-6e3c-43fe-8aee-999e85445822',\n",
       " 'd9281864-737a-4f84-babe-b47a4c6ac5c2',\n",
       " '75c84abf-2b75-49e0-a793-e96741dc8b3c',\n",
       " 'e5328daf-7649-4afb-b360-961e9545b57a',\n",
       " '632e4761-2ebf-4023-a5f5-3b45fc384f29',\n",
       " '908a0910-0408-4166-ae71-6eb543d7b409',\n",
       " 'dd31d01b-4532-4fe4-9585-9c38b252557e',\n",
       " '0ea16b79-fae7-4c44-a726-b4c6ca142539',\n",
       " '76afd011-dac2-4caa-8410-08dae15134c7',\n",
       " 'c26ff23a-c87e-495e-ada5-3e03500d5b85',\n",
       " 'c22015e1-646d-449a-a2ae-63bb8641c5be',\n",
       " '1c4b2cc5-f34e-4ff2-964b-e1bc892cc35a',\n",
       " '797a1b84-7139-4433-bbdc-8132cb16ee3d',\n",
       " '9cf58c6f-e76b-4a2e-8369-74ec7a1196c6',\n",
       " '825a4462-a1ba-40b3-821a-8842819c6bae',\n",
       " 'e2853dcf-f169-4de2-9071-3be2345d4450',\n",
       " 'b43b4542-cf5c-47fc-819f-0bcbb45b8446',\n",
       " '4575fcf5-389c-4fd4-a73a-bd346b7cf16c',\n",
       " '69b40134-f06d-4b77-bdac-b8fa2401aa45',\n",
       " '71090fd2-3360-4e1d-b379-6db88a49fdac',\n",
       " '4a43070c-34cf-4a69-853f-e485be920197',\n",
       " '3565d253-a69f-49de-b8f2-c11c1221e83e',\n",
       " '0127940a-ffa5-4d30-b0c8-cddae44998a0',\n",
       " 'b90aa268-73a0-4728-877e-c41aa671dac6',\n",
       " 'b974885f-bf81-45a8-906c-9e72e2afcbda',\n",
       " 'bc080da2-cb25-4a8b-b5ae-a995cddea994',\n",
       " 'bd80f6a5-86c2-4dad-a04a-e65427886427',\n",
       " '10bb98b0-ae4b-4cf9-8ae5-a24cccb6a596',\n",
       " 'bd674c74-ec66-468b-804c-45e41222aed6',\n",
       " '342c0874-c0cc-44ad-ad29-442354c7cdac',\n",
       " '8ca653a8-450c-46df-9f60-e23e16ec5ace',\n",
       " '82d8dfe5-3ab0-4747-a4b8-17903e1406fc',\n",
       " '5811cb8f-ea23-4a9e-8c0c-dd7d2bab2a43',\n",
       " '21ee28a1-96c9-4b72-a288-04ebd1839397',\n",
       " '030a0275-95e7-4db7-80cf-63e3bae76f22',\n",
       " '21610efe-d2ca-4641-9372-7f1337f04343',\n",
       " '22c00439-649d-4f63-ac40-73a60bb9b2bd',\n",
       " 'd85be2ae-d81c-4b57-b581-cd30904a858a',\n",
       " '4279261b-bbe0-42d7-af12-e665f7d1e4a6',\n",
       " '6b33625a-155a-4254-9cd9-d6c71d69d5a9',\n",
       " '6eafd886-7a2b-4509-93a6-d0f378970fb2',\n",
       " 'c461090e-51aa-4c0c-b7d8-edeb03f961a2',\n",
       " '2c5f8804-a2fb-4e75-8062-fd588bb18a77',\n",
       " '6e6dee57-5e51-418c-8010-4b5838424584',\n",
       " '6e1e9663-375c-42f5-aa39-f760e7b76149',\n",
       " '25732751-a078-4dad-bbd9-e73760a383c4',\n",
       " '4524cf31-6d0f-4bab-9a54-e4d7a9fb601d',\n",
       " 'dc5eb94d-e74b-4c92-a507-adddc53cf295',\n",
       " '83d5f00d-a9e8-4060-888e-8192c766b203',\n",
       " '51b2a68a-24bb-470e-ac0b-08bde1cb2c76',\n",
       " '9fbccb36-36b3-4606-99a0-869e32294350',\n",
       " '054e93be-0900-4a38-8cfe-940b6cfa2050',\n",
       " 'd2702a9b-d579-4032-9923-bf3c6c4ee594',\n",
       " 'dde9350d-1e39-4e3e-b81a-debbd9ee7bc0',\n",
       " '8e157a25-b91f-4feb-ad10-d61d6bc50192',\n",
       " '62c76dfb-b324-4090-863f-c14da1099947',\n",
       " '09eb7f5f-a0c9-4477-be4c-194ce87cd9ed',\n",
       " 'f7eaaa11-e8fb-4660-9b83-5a2224810f1a',\n",
       " '83ea1cf7-3f09-4320-b816-629e6f934e99',\n",
       " '424e73cb-a012-4360-9932-a276912d652a',\n",
       " '616d66f5-5cfd-4563-9ae5-62da3d5eea6c',\n",
       " 'def43de5-82c9-4fd8-9f9b-f2c97ecf80d9',\n",
       " '1b9aad56-b9d8-4b58-88cd-65d9e2ef927e',\n",
       " '7c2358ea-f25d-4a58-8eb1-716460dbbfad',\n",
       " 'fbe1c858-f89b-4209-ad20-2652430ab3e0',\n",
       " '85336d0f-8afb-4b39-867a-6dcf350f9aa5',\n",
       " '493d8f81-e05a-4fff-a54e-0530bc6ebe4b',\n",
       " '7ad6b510-e1f1-4c08-a478-87f26da77df6',\n",
       " 'eacc4065-4271-4a4f-a8e1-b44d845256d1',\n",
       " 'bd562012-fd40-4be7-973d-d85a14bd16db',\n",
       " '49adf367-6b2f-48a0-9d1d-23607a2c583d',\n",
       " '651dd532-631a-49ac-9164-c43c3e089ab3',\n",
       " '58bcf7b1-1968-420e-88d6-568abfb2a877',\n",
       " '6d561a96-53c6-4042-867c-05831d6fe36a',\n",
       " '816bf1a2-dc74-46c7-8ab2-07cbd1d96839',\n",
       " '5502e320-a874-4117-baac-db8bc78747e0',\n",
       " '30df03b5-c5f2-482a-9fed-e0037d702639',\n",
       " '9053799e-4f7f-4c18-86e6-12b8b2c2ec9a',\n",
       " '59edcade-9782-4e14-a114-d51336d5edb0',\n",
       " '033c7c5c-f9be-4b3a-b676-d3f91093ad5b',\n",
       " 'ff3ab5a5-0165-4ee4-a599-3b0e99665fbc',\n",
       " 'bc012d54-b629-4ba1-84f2-34186b17be24',\n",
       " '4514e073-e10f-403c-ace0-dc375e624b3e',\n",
       " 'ae2ffc5d-e038-4aac-b6b0-07cad0696a94',\n",
       " 'de240431-765b-4485-a62b-491df980cfa8',\n",
       " '54cb4dc6-8021-4d08-a9c5-c459056451dc',\n",
       " '8f51bdfc-0d1a-4382-aa2f-dbbb3054904f',\n",
       " '8a90e232-77b6-49be-b475-a19f2a7cabaa',\n",
       " '3d756803-3fb5-4c50-ae80-b1f3103a3dbd',\n",
       " 'e4ac21c4-70a5-4067-9f6f-aa5fab8af477',\n",
       " '551fd5c6-452f-48d9-a1fb-511401eeb3df',\n",
       " 'ec5fd2fd-2261-4129-812d-99c74c5c2296',\n",
       " 'd2d421c6-b978-4136-ba6e-2c777abaebd9',\n",
       " '6c251457-4ead-42f1-a65d-3941d08a489f',\n",
       " '3ecec794-4808-49eb-a275-d5b199dde2dd',\n",
       " '0e8dde0d-682b-4d9f-ad9d-4913cf4e97e7',\n",
       " '847298cc-048e-4f2f-be26-ef8e8c3a0ad5',\n",
       " '2a602055-4deb-40f8-9b6d-125864a1cf9b',\n",
       " '65669f26-c1e5-459a-9e84-db02d4b4ef00',\n",
       " '74e9b220-0561-4b62-a791-c9bf5af8266a',\n",
       " 'bf39c767-d31c-4bcc-8b7a-ea7fdf44dd14',\n",
       " 'fce5db30-6cf7-42ff-bff2-9486ad1f8c82',\n",
       " '81c96a98-e24e-4b5b-b255-c6c87041d0a3',\n",
       " '07848621-832e-4ad9-8214-699029c79f16',\n",
       " 'fe011118-c8be-4d87-9ddb-9a964399cd33',\n",
       " '5e474a2b-9941-4aa2-a1ef-ec19ebe872d5',\n",
       " '1e617f57-546e-4cba-8198-e263fbab00aa',\n",
       " 'e4f719f5-f238-44cc-aa6e-218913837912',\n",
       " '44a1c723-0c3b-440c-af80-11320bbee230',\n",
       " 'e5873f70-7987-4617-b596-3560eb8bb387',\n",
       " 'c0c8e131-12bb-4413-a14e-7563034607cc',\n",
       " 'b3478890-565f-4244-b782-330be7f8e2d5',\n",
       " '43820f29-40fd-4357-be0a-056104075571',\n",
       " 'a7f1b3f2-3d22-4941-b8f2-25d26981748e',\n",
       " '21e6b4cb-3bfd-42cd-9cd7-b4bedfeb8135',\n",
       " '86351366-4bfc-48ba-8e13-03610c1af80a',\n",
       " 'bf00732f-1d52-4469-90da-9f573e084d28',\n",
       " '98ab0ffd-dd1a-40ec-8e4e-2a0e6b2d12b3',\n",
       " '0c818e4f-17b3-48bc-a8e8-7a7bcd263d52',\n",
       " '57a03379-dc31-4755-b03b-c4912f48ae04',\n",
       " '26904e19-afdd-4409-b2a4-24338b1d2b8d',\n",
       " '68baa109-83a5-4b30-994c-8a1e0c8f07c8',\n",
       " '5d4d8338-850e-4495-bef3-3042f892f3e8',\n",
       " '806a743f-0767-4363-9b5e-227720b43f1f',\n",
       " 'ac250e6b-7e16-4b4c-9e48-755c51815655',\n",
       " 'b640dea2-6382-4f0a-972b-dff33ccb705f',\n",
       " 'd97cd07d-8a26-41fe-ab2e-dd59a4ef1859',\n",
       " 'ceda8112-8b5f-49bd-ab5f-3566b37c37cc',\n",
       " 'cc17bdd6-0955-40bc-a26a-0b26d91f39bb',\n",
       " '10bfd483-ffb3-4426-9436-de505c4f7370',\n",
       " 'cfbd75c7-2a95-49eb-b199-852e6f52c5be',\n",
       " '325af35c-3ced-4604-bc07-eae9cb23b756',\n",
       " '80a5847e-9b37-4c71-88b3-9735206a5e50',\n",
       " 'ca95aafe-2cbe-44d2-b438-bf5fae02f7d4',\n",
       " '1c73d328-b5eb-40f0-a245-375e229026ef',\n",
       " 'bc6bdc6f-2fe3-4f05-b9e7-04b82d34b553',\n",
       " '5fa2eba3-fd36-4143-82bf-a89019128a7d',\n",
       " '6b39bfef-ea41-4775-bd68-6246d6b92f4c',\n",
       " '3cd310cd-be60-4e34-8ec1-202c699ee6eb',\n",
       " '854d76be-667d-4cfd-a377-f3ce859c0059',\n",
       " '0d3deccc-54d5-4cd5-a459-cf35a38e738a',\n",
       " '87535d5f-ce40-4f88-b111-b408b561002b',\n",
       " 'ebb12ab4-afd8-48ef-bb90-ad634396e605',\n",
       " 'a9d69b53-52ec-4c43-926f-7d25e31e1f89',\n",
       " '4d68c42c-50c8-4ef9-afd3-d1c77eec043f',\n",
       " '3dddf78f-11b6-4c87-83c4-bdecc5425a11',\n",
       " '35b83567-78b2-4805-bf59-83523f96cf25',\n",
       " '0827e345-31dd-4df6-97bd-c970709ad47a',\n",
       " '1fc70668-b196-4753-b44a-3d91d33b4d53',\n",
       " '4e63843b-f6f7-4825-a100-29defd50e87f',\n",
       " 'f4f36255-a5bc-4c96-a0d8-c6410bffa0b4',\n",
       " '2a3efd3a-fb5c-405b-9c3c-3ebba6833a2f',\n",
       " '50f5a89b-b0f8-45cf-b4e2-5443ade9f399',\n",
       " '2fd6b757-613f-4815-90bd-88a515c7ef03',\n",
       " 'b1dc93ca-8de3-4a67-a016-37a4f88a2eaa',\n",
       " 'ec08f347-5160-405a-8fe8-21dfb8bee1b8',\n",
       " '1fd717ed-eb14-42af-a4d1-48c5c2d6b972',\n",
       " 'fdc10d1e-8646-43eb-bde6-9bcfa20dab33',\n",
       " 'caca8815-b19a-469c-8a0a-fa2f5c0e8ae6',\n",
       " '26ed8c35-ca47-4428-9265-df5d3f17ca85',\n",
       " 'e8bada80-e65b-47af-9e5e-5cb00d500855',\n",
       " '68bf6270-e1aa-4d8e-aee2-823a7985fbff',\n",
       " '03e1ac61-45f1-4d35-a270-2401a47c1f70',\n",
       " '794365c1-d022-499e-a10b-4df248c8c88f',\n",
       " 'a510e07e-c72d-497e-9787-c849a2f483d2',\n",
       " 'e0982398-54a1-442d-b5b6-a8e9d283a3ce',\n",
       " '7355e65d-b474-4d3f-b231-53d4216a8294',\n",
       " '0eed7656-e9ff-4c21-96c1-673f462a4725',\n",
       " 'ed155492-f802-4301-ba3d-32bcdefa4854',\n",
       " '50a73f7b-d701-4e43-9514-448802bdd786',\n",
       " 'f8e71649-6e73-4199-b325-c2b020cd1366',\n",
       " 'c03eb096-4d9e-4136-a7d5-792073776da0',\n",
       " 'f8199fdc-07d3-457f-8f95-63a8b44851d5',\n",
       " '89016e0e-6cbd-45b6-b22a-38c06cc996dd',\n",
       " '26e9e738-cc24-47ce-9c6a-5bb4cc67dca6',\n",
       " '6cf8798b-000f-4c8c-8d95-f8884286a193',\n",
       " '5df1d43b-3310-4f21-889b-f9e42bb09023',\n",
       " '10ad568b-d007-4634-a4b6-f7ed6b737d23',\n",
       " 'ce4ed13b-8820-4d00-9839-10668d67345f',\n",
       " '1ef54372-0903-4244-8927-84e4a0b0c885',\n",
       " '408d755f-c486-4497-a3ca-9125ef8ef52c',\n",
       " '0dec9b94-abae-43cd-8ab1-c946d54c08a4',\n",
       " '7ea187bf-db99-4c89-b79b-b6f7048bad1a',\n",
       " '6156db0d-1007-4796-91e9-bde77ec9c6f5',\n",
       " 'a77964a1-7cad-4e28-b7c2-a135f49a0474',\n",
       " '314e80cb-a809-4869-8517-1c7a13383172',\n",
       " '7c3b19b7-aa14-4e89-a38f-ec85a8aa9b4e',\n",
       " 'f3e29a2f-9e81-4991-91d3-8755dace8248',\n",
       " '529b6185-1bf1-41c0-bbc3-f16fac9c5993',\n",
       " '1610130d-1014-42ea-8a80-e8a6060cbc4e',\n",
       " 'cc6a949b-7212-41eb-9508-73658b5c3250',\n",
       " '8524d95d-5a2e-4683-8970-2e4f2a95c5ac',\n",
       " 'ca690ed3-0699-4435-b81d-faeb11aa9f83',\n",
       " '8ddccf3c-44a6-43ee-a888-9438a751f842',\n",
       " '4729f231-f745-41b7-af1c-7b76dcac6697',\n",
       " '059ea99e-4964-4355-9686-86dd0bfc17cc',\n",
       " '42babd44-2abf-475d-a19d-5d592516234c',\n",
       " '3cb82b15-b65c-451a-b1ee-9f9cc8c9e02d',\n",
       " 'b51b1002-7bdb-4d70-9812-1fcdd103b465',\n",
       " '9c39f6e8-15aa-4197-a017-b2acbece8716',\n",
       " '5fdc849e-590c-4c57-a3da-12ae72bf891b',\n",
       " 'bb9cbcd2-2b8f-4475-a3d3-0f9090bdc1ff',\n",
       " 'a291fb40-86a6-4b29-bd8d-36632d4ad717',\n",
       " 'f8fa4ab8-39d9-4008-9308-35d5171d1b9e',\n",
       " '568e40d6-caa6-4e25-9038-fa67717f3e4c',\n",
       " 'b6356d78-7b87-46b0-850b-3107784c166e',\n",
       " 'a67c55de-4a19-47d7-a503-7456caf28f47',\n",
       " '154cf2c6-0322-4b0d-b8a0-c3b7675c46b7',\n",
       " 'c213b322-b5a4-4dce-8668-97f87e7c3537',\n",
       " 'bbf6b023-40ff-4459-95c5-c05827d76558',\n",
       " '4ec938c7-2481-4754-a24b-707a3d37988d',\n",
       " 'a5fbb8fc-313a-4105-85e1-9fb8ab9b2abf',\n",
       " 'e9c6255d-d85f-40da-b214-c36f3c77319d',\n",
       " 'c9e116db-5134-4b6c-9474-34c628dfe1a2',\n",
       " 'd62a340b-b6b1-4315-b2b2-d87d301ff9e5',\n",
       " '4dd9c88c-7432-4c3c-9716-6c6c399ee028',\n",
       " '0fa4326b-0941-499c-833e-3ea9d9db68d4',\n",
       " '62affcdf-71fa-4766-a21f-f25d64bdcbb8',\n",
       " 'b4ae4602-5441-4339-9479-e5ae018c0cad',\n",
       " '47fdfdbf-8098-4307-83b7-f7d1582e4c09',\n",
       " '8f4d9aff-a610-446b-a155-f857b67c61e4',\n",
       " '814da637-18dd-4f86-b5e7-f6225a431bab',\n",
       " '6461622c-382e-4c3f-9366-2d372630916a',\n",
       " '2a906afe-be51-470e-bec0-3b8cf9a3f6a0',\n",
       " 'de1ce2f1-546b-4d92-9b7e-1215d79ade18',\n",
       " '1e1bde84-441c-4bd5-8df7-b3cc7f02842c',\n",
       " '0657b05e-a11d-4b35-86c3-7d9d43e59375',\n",
       " 'cb4dd6a4-1d8a-4327-b2a7-17fee29c4027',\n",
       " '6bcd6fae-7351-4a4b-8ce5-96786bb173ec',\n",
       " 'f220c580-99c6-4730-9169-6a33edf2c4bd',\n",
       " '2f7e8905-d583-4a1a-badb-5534861edf4a',\n",
       " 'ae2a758d-474c-4781-b9ea-15391b8985e0',\n",
       " 'a3b9ec19-fc4f-44ad-9a13-600a9e02eeeb',\n",
       " 'fb7c03b4-9f77-49d6-8f68-0a4d4dfe9adb',\n",
       " 'f976a8c2-d35a-4018-adb0-bbd5a260d25a',\n",
       " 'b828fee5-3173-48d4-8717-88459c41fecf',\n",
       " '791e3f04-bf34-4894-9114-b581fb284c7b',\n",
       " 'a64e7a63-6248-4d97-99b9-9554b911c094',\n",
       " 'f062895f-7ab6-4a89-9955-a3d492d967cf',\n",
       " '9a923c80-a289-482a-b9c0-ab6ee7fe2b0f',\n",
       " '8e405d58-a921-4ff4-a3fd-34a0fccc68f7',\n",
       " 'd431dbda-dca2-4d98-b253-1a8a1bfc7803',\n",
       " 'fc61890a-48d0-46fa-b51a-c2dc6aaa0a13',\n",
       " 'abb7c279-4ae4-41c6-91d9-62c09fc95fc2',\n",
       " '5ea53047-cdde-4a43-94ee-36705e25ce43',\n",
       " '109f9255-09c8-4443-914e-10290af7c2aa',\n",
       " '86138764-1336-493e-9059-d5f4c6262444',\n",
       " 'd1e144cb-6e5c-4a5e-bcb0-c4edd9f3c69e',\n",
       " 'debce3c9-96fe-41ac-8575-84e6d87af05b',\n",
       " '68ef9ddf-0bdf-4d18-9319-95cad042e279',\n",
       " '08556ee2-7db1-40b7-8c05-5226304c3b24',\n",
       " 'd242d718-1784-4835-9fbc-205afedee133',\n",
       " '53294277-d88a-4fae-9c5a-0c22767748fa',\n",
       " '974ca420-cb89-4156-af84-887c00c2655d',\n",
       " 'cb448c1c-5718-433e-b6a8-b9983d3bfb7a',\n",
       " '735c549d-a78d-4ebc-9b4f-194bb787f930',\n",
       " '4679d5b8-dcf1-4f6c-a982-4e35e77b61ae',\n",
       " '4200532c-af1b-4825-9311-f089e321b54b',\n",
       " '391a72db-995d-4e0f-8790-f090c50cddb7',\n",
       " 'b7eaa743-cfa4-4b3b-8eb8-b38d90e40b2b',\n",
       " 'ea7acfc4-b7a2-4f4b-915a-e1f79db5be59',\n",
       " '7f5a669f-0e55-44ee-9c2c-3865ed0d9040',\n",
       " 'c37cbaa2-4cbd-47a0-b3e2-11a828e4da39']"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "doc_splits[0]\n",
    "vector_store.add_documents(doc_splits)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "a7b93bfe",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 2. Create a retriever tool¶\n",
    "# Use an in-memory vector store and OpenAI embeddings:\n",
    "\n",
    "from langchain_community.embeddings import DashScopeEmbeddings\n",
    "from langchain_postgres import PGVector\n",
    "\n",
    "EMBEDDING_URL = \"https://dashscope.aliyuncs.com/compatible-mode/v1\"\n",
    "EMBEDDING_KEY = \"sk-8d7ac86d58cd49c8966a0aeea75f1c28\"\n",
    "EMBEDDING_MODEL = \"text-embedding-v3\"\n",
    "POSTGRES_USER = \"docker\"\n",
    "POSTGRES_PASSWORD = \"docker\"\n",
    "POSTGRES_HOST = \"localhost\"\n",
    "POSTGRES_PORT = \"5432\"\n",
    "POSTGRES_DB = \"streamlit_generic\"\n",
    "VECTOR_SIZE = 1024\n",
    "\n",
    "embeddings = DashScopeEmbeddings(\n",
    "    model=\"text-embedding-v3\", dashscope_api_key=EMBEDDING_KEY\n",
    ")\n",
    "connection = (\n",
    "    f\"postgresql+psycopg://{POSTGRES_USER}:{POSTGRES_PASSWORD}@{POSTGRES_HOST}\"\n",
    "    f\":{POSTGRES_PORT}/{POSTGRES_DB}\"\n",
    ")\n",
    "collection_name = \"test_vectorstore\"\n",
    "vector_store = PGVector(\n",
    "    embeddings=embeddings,\n",
    "    collection_name=collection_name,\n",
    "    connection=connection,\n",
    "    use_jsonb=True,\n",
    ")\n",
    "retriever = vector_store.as_retriever(search_type=\"mmr\", search_kwargs={\"k\": 1})\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2bbffdc8",
   "metadata": {},
   "outputs": [],
   "source": [
    "# Create a retriever tool using LangChain's prebuilt create_retriever_tool:\n",
    "\n",
    "from langchain.tools.retriever import create_retriever_tool\n",
    "retriever_tool = create_retriever_tool(\n",
    "    retriever,\n",
    "    \"retrieve_blog_posts\",\n",
    "    \"Search and return information about Lilian Weng blog posts.\",\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "1b39ae12",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'(Note: Some work defines reward tampering as a distinct category of misalignment behavior from reward hacking. But I consider reward hacking as a broader concept here.)\\nAt a high level, reward hacking can be categorized into two types: environment or goal misspecification, and reward tampering.'"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Test the tool:\n",
    "retriever_tool.invoke({\"query\": \"types of reward hacking\"})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "9bfa2df9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 3. Generate query¶\n",
    "from langgraph.graph import MessagesState\n",
    "from langchain.chat_models import init_chat_model\n",
    "import os\n",
    "os.environ[\"DEEPSEEK_API_KEY\"] = \"sk-9cc450ae42c04f3a8b4c46fc56f6d295\"\n",
    "key = \"sk-9cc450ae42c04f3a8b4c46fc56f6d295\"\n",
    "response_model = init_chat_model(\"deepseek-chat\", model_provider=\"deepseek\")\n",
    "response_model.invoke(\"Hello, world!\")\n",
    "\n",
    "\n",
    "def generate_query_or_respond(state: MessagesState):\n",
    "    \"\"\"Call the model to generate a response based on the current state. Given\n",
    "    the question, it will decide to retrieve using the retriever tool, or simply respond to the user.\n",
    "    \"\"\"\n",
    "    response = (\n",
    "        response_model\n",
    "        .bind_tools([retriever_tool]).invoke(state[\"messages\"])\n",
    "    )\n",
    "    return {\"messages\": [response]}\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "dc81816b",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
      "\n",
      "Hello! How can I help you today? I have access to information about Lilian Weng's blog posts if you're interested in learning about her content.\n"
     ]
    }
   ],
   "source": [
    "# Try it on a random input:\n",
    "\n",
    "input = {\"messages\": [{\"role\": \"user\", \"content\": \"hello!\"}]}\n",
    "generate_query_or_respond(input)[\"messages\"][-1].pretty_print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "2d3cddff",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
      "\n",
      "I'll search for Lilian Weng's blog posts about reward hacking to see what she says about the different types.\n",
      "Tool Calls:\n",
      "  retrieve_blog_posts (call_00_QAMS9bhrAxR6IxFFUG7w0Me5)\n",
      " Call ID: call_00_QAMS9bhrAxR6IxFFUG7w0Me5\n",
      "  Args:\n",
      "    query: reward hacking types\n"
     ]
    }
   ],
   "source": [
    "input = {\n",
    "    \"messages\": [\n",
    "        {\n",
    "            \"role\": \"user\",\n",
    "            \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n",
    "        }\n",
    "    ]\n",
    "}\n",
    "generate_query_or_respond(input)[\"messages\"][-1].pretty_print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "d74e4f22",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 4. Grade documents¶\n",
    "from pydantic import BaseModel, Field\n",
    "from typing import Literal\n",
    "\n",
    "GRADE_PROMPT = (\n",
    "    \"You are a grader assessing relevance of a retrieved document to a user question. \\n \"\n",
    "    \"Here is the retrieved document: \\n\\n {context} \\n\\n\"\n",
    "    \"Here is the user question: {question} \\n\"\n",
    "    \"If the document contains keyword(s) or semantic meaning related to the user question, grade it as relevant. \\n\"\n",
    "    \"Give a binary score 'yes' or 'no' score to indicate whether the document is relevant to the question.\"\n",
    ")\n",
    "\n",
    "\n",
    "class GradeDocuments(BaseModel):\n",
    "    \"\"\"Grade documents using a binary score for relevance check.\"\"\"\n",
    "\n",
    "    binary_score: str = Field(\n",
    "        description=\"Relevance score: 'yes' if relevant, or 'no' if not relevant\"\n",
    "    )\n",
    "\n",
    "\n",
    "# grader_model = init_chat_model(\"openai:gpt-4.1\", temperature=0)\n",
    "grader_model = init_chat_model(\"deepseek-chat\", model_provider=\"deepseek\")\n",
    "\n",
    "def grade_documents(\n",
    "    state: MessagesState,\n",
    ") -> Literal[\"generate_answer\", \"rewrite_question\"]:\n",
    "    \"\"\"Determine whether the retrieved documents are relevant to the question.\"\"\"\n",
    "    question = state[\"messages\"][0].content\n",
    "    context = state[\"messages\"][-1].content\n",
    "    prompt = GRADE_PROMPT.format(question=question, context=context)\n",
    "    response = (\n",
    "        grader_model\n",
    "        .with_structured_output(GradeDocuments).invoke(\n",
    "            [{\"role\": \"user\", \"content\": prompt}]\n",
    "        )\n",
    "    )\n",
    "    score = response.binary_score\n",
    "    if score == \"yes\":\n",
    "        return \"generate_answer\"\n",
    "    else:\n",
    "        return \"rewrite_question\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "607fa20c",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'rewrite_question'"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Run this with irrelevant documents in the tool response:\n",
    "\n",
    "from langchain_core.messages import convert_to_messages\n",
    "\n",
    "input = {\n",
    "    \"messages\": convert_to_messages(\n",
    "        [\n",
    "            {\n",
    "                \"role\": \"user\",\n",
    "                \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n",
    "            },\n",
    "            {\n",
    "                \"role\": \"assistant\",\n",
    "                \"content\": \"\",\n",
    "                \"tool_calls\": [\n",
    "                    {\n",
    "                        \"id\": \"1\",\n",
    "                        \"name\": \"retrieve_blog_posts\",\n",
    "                        \"args\": {\"query\": \"types of reward hacking\"},\n",
    "                    }\n",
    "                ],\n",
    "            },\n",
    "            {\"role\": \"tool\", \"content\": \"meow\", \"tool_call_id\": \"1\"},\n",
    "        ]\n",
    "    )\n",
    "}\n",
    "grade_documents(input)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "99e211ee",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'generate_answer'"
      ]
     },
     "execution_count": 23,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Confirm that the relevant documents are classified as such:\n",
    "input = {\n",
    "    \"messages\": convert_to_messages(\n",
    "        [\n",
    "            {\n",
    "                \"role\": \"user\",\n",
    "                \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n",
    "            },\n",
    "            {\n",
    "                \"role\": \"assistant\",\n",
    "                \"content\": \"\",\n",
    "                \"tool_calls\": [\n",
    "                    {\n",
    "                        \"id\": \"1\",\n",
    "                        \"name\": \"retrieve_blog_posts\",\n",
    "                        \"args\": {\"query\": \"types of reward hacking\"},\n",
    "                    }\n",
    "                ],\n",
    "            },\n",
    "            {\n",
    "                \"role\": \"tool\",\n",
    "                \"content\": \"reward hacking can be categorized into two types: environment or goal misspecification, and reward tampering\",\n",
    "                \"tool_call_id\": \"1\",\n",
    "            },\n",
    "        ]\n",
    "    )\n",
    "}\n",
    "grade_documents(input)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "53549afe",
   "metadata": {},
   "outputs": [],
   "source": [
    "REWRITE_PROMPT = (\n",
    "    \"Look at the input and try to reason about the underlying semantic intent / meaning.\\n\"\n",
    "    \"Here is the initial question:\"\n",
    "    \"\\n ------- \\n\"\n",
    "    \"{question}\"\n",
    "    \"\\n ------- \\n\"\n",
    "    \"Formulate an improved question:\"\n",
    ")\n",
    "\n",
    "\n",
    "def rewrite_question(state: MessagesState):\n",
    "    \"\"\"Rewrite the original user question.\"\"\"\n",
    "    messages = state[\"messages\"]\n",
    "    question = messages[0].content\n",
    "    prompt = REWRITE_PROMPT.format(question=question)\n",
    "    response = response_model.invoke([{\"role\": \"user\", \"content\": prompt}])\n",
    "    return {\"messages\": [{\"role\": \"user\", \"content\": response.content}]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "a965ef5f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Of course. The original question is a good starting point but can be significantly improved for precision and depth. Here's a breakdown of the reasoning and an improved version.\n",
      "\n",
      "### Reasoning About the Underlying Semantic Intent\n",
      "\n",
      "The user's question has two key components:\n",
      "\n",
      "1.  **The Source:** \"Lilian Weng\" - This refers to a specific, influential researcher (a Staff Research Scientist at OpenAI). The user isn't asking for a general definition; they are looking for her specific framing or taxonomy of the concept. This implies a need for an authoritative, well-structured answer.\n",
      "2.  **The Concept:** \"types of reward hacking\" - \"Reward hacking\" is a well-known problem in AI alignment where an agent finds a way to achieve a high reward signal that doesn't align with the designer's true intent. The user wants a *categorization* or *taxonomy* of the different ways this can happen, not just a simple definition.\n",
      "\n",
      "The initial question is functional but vague. An improved question would:\n",
      "*   Specify the **format** of her work (e.g., a blog post).\n",
      "*   Prompt a more structured answer that lists and explains the types.\n",
      "*   Acknowledge that her writing is a synthesis of known concepts, not necessarily the originator of the types themselves.\n",
      "\n",
      "---\n",
      "\n",
      "### Improved Question\n",
      "\n",
      "Based on the semantic intent, here is a clearer and more actionable question:\n",
      "\n",
      "**\"In her blog post on AI alignment, how does Lilian Weng categorize the different types of reward hacking, and what are examples of each?\"**\n",
      "\n",
      "### Why This is an Improvement:\n",
      "\n",
      "*   **Specific Source:** It pinpoints the likely source material (\"her blog post on AI alignment\"), making the answer easier to locate and verify. Her post [\"Improving Reinforcement Learning with Human Feedback\"](https://lilianweng.github.io/posts/2018-04-08-human-preferences/) is a canonical reference for this topic.\n",
      "*   **Action-Oriented:** \"How does she categorize...\" prompts a structured response listing the types.\n",
      "*   **Requests Context:** \"...and what are examples of each?\" This asks for the crucial detail that makes the taxonomy understandable and practical.\n",
      "*   **Accurate Framing:** It correctly frames her work as a *categorization* of existing ideas within a broader educational article.\n",
      "\n",
      "### Expected Answer to the Improved Question:\n",
      "\n",
      "An ideal response would state that in her blog post, Lilian Weng describes reward hacking as a major challenge and outlines several common types, which include:\n",
      "\n",
      "1.  **Optimizing for the Proxy:** The agent maximizes the reward *signal* (the proxy for true goal) at the expense of the true objective.\n",
      "    *   *Example:* A boat race agent rewarded for hitting finishing gates learns to crash into them and circle endlessly instead of completing the course.\n",
      "\n",
      "2.  **Side Effects:** The agent achieves its goal but causes unnecessary or harmful changes to the environment in the process.\n",
      "    *   *Example:* A vacuum cleaning robot rewarded for eliminating dust learns to disable its own dust sensor so it always reads zero, or simply vacuums up piles of dirt without ever depositing them in the bin, creating a mess.\n",
      "\n",
      "3.  **Reward Engineering:** The agent exhibits behavior that is technically correct based on a flawed reward function designed by humans.\n",
      "    *   *Example:* An agent trained to survive in a game is rewarded for having high health. It learns to pause the game indefinitely to avoid any risk of losing health.\n",
      "\n",
      "4.  **Self-Preservation Incentive:** In environments where termination stops the reward stream, the agent learns to avoid terminal states at all costs, even if termination is part of the intended task.\n",
      "    *   *Example:* A chess-playing agent learns to avoid checkmating its opponent because the game (and its source of reward) would then end. Instead, it plays to prolong the game infinitely.\n",
      "\n",
      "This structure directly and efficiently fulfills the user's likely intent behind the original question.\n"
     ]
    }
   ],
   "source": [
    "input = {\n",
    "    \"messages\": convert_to_messages(\n",
    "        [\n",
    "            {\n",
    "                \"role\": \"user\",\n",
    "                \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n",
    "            },\n",
    "            {\n",
    "                \"role\": \"assistant\",\n",
    "                \"content\": \"\",\n",
    "                \"tool_calls\": [\n",
    "                    {\n",
    "                        \"id\": \"1\",\n",
    "                        \"name\": \"retrieve_blog_posts\",\n",
    "                        \"args\": {\"query\": \"types of reward hacking\"},\n",
    "                    }\n",
    "                ],\n",
    "            },\n",
    "            {\"role\": \"tool\", \"content\": \"meow\", \"tool_call_id\": \"1\"},\n",
    "        ]\n",
    "    )\n",
    "}\n",
    "\n",
    "response = rewrite_question(input)\n",
    "print(response[\"messages\"][-1][\"content\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "b690cfbc",
   "metadata": {},
   "outputs": [],
   "source": [
    "GENERATE_PROMPT = (\n",
    "    \"You are an assistant for question-answering tasks. \"\n",
    "    \"Use the following pieces of retrieved context to answer the question. \"\n",
    "    \"If you don't know the answer, just say that you don't know. \"\n",
    "    \"Use three sentences maximum and keep the answer concise.\\n\"\n",
    "    \"Question: {question} \\n\"\n",
    "    \"Context: {context}\"\n",
    ")\n",
    "\n",
    "\n",
    "def generate_answer(state: MessagesState):\n",
    "    \"\"\"Generate an answer.\"\"\"\n",
    "    question = state[\"messages\"][0].content\n",
    "    context = state[\"messages\"][-1].content\n",
    "    prompt = GENERATE_PROMPT.format(question=question, context=context)\n",
    "    response = response_model.invoke([{\"role\": \"user\", \"content\": prompt}])\n",
    "    return {\"messages\": [response]}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "fbfdb8bf",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
      "\n",
      "Lilian Weng states that reward hacking can be categorized into two types. These are environment or goal misspecification and reward tampering.\n"
     ]
    }
   ],
   "source": [
    "input = {\n",
    "    \"messages\": convert_to_messages(\n",
    "        [\n",
    "            {\n",
    "                \"role\": \"user\",\n",
    "                \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n",
    "            },\n",
    "            {\n",
    "                \"role\": \"assistant\",\n",
    "                \"content\": \"\",\n",
    "                \"tool_calls\": [\n",
    "                    {\n",
    "                        \"id\": \"1\",\n",
    "                        \"name\": \"retrieve_blog_posts\",\n",
    "                        \"args\": {\"query\": \"types of reward hacking\"},\n",
    "                    }\n",
    "                ],\n",
    "            },\n",
    "            {\n",
    "                \"role\": \"tool\",\n",
    "                \"content\": \"reward hacking can be categorized into two types: environment or goal misspecification, and reward tampering\",\n",
    "                \"tool_call_id\": \"1\",\n",
    "            },\n",
    "        ]\n",
    "    )\n",
    "}\n",
    "\n",
    "response = generate_answer(input)\n",
    "response[\"messages\"][-1].pretty_print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "e6e144a3",
   "metadata": {},
   "outputs": [],
   "source": [
    "from langgraph.graph import StateGraph, START, END\n",
    "from langgraph.prebuilt import ToolNode\n",
    "from langgraph.prebuilt import tools_condition\n",
    "\n",
    "workflow = StateGraph(MessagesState)\n",
    "\n",
    "# Define the nodes we will cycle between\n",
    "workflow.add_node(generate_query_or_respond)\n",
    "workflow.add_node(\"retrieve\", ToolNode([retriever_tool]))\n",
    "workflow.add_node(rewrite_question)\n",
    "workflow.add_node(generate_answer)\n",
    "\n",
    "workflow.add_edge(START, \"generate_query_or_respond\")\n",
    "\n",
    "# Decide whether to retrieve\n",
    "workflow.add_conditional_edges(\n",
    "    \"generate_query_or_respond\",\n",
    "    # Assess LLM decision (call `retriever_tool` tool or respond to the user)\n",
    "    tools_condition,\n",
    "    {\n",
    "        # Translate the condition outputs to nodes in our graph\n",
    "        \"tools\": \"retrieve\",\n",
    "        END: END,\n",
    "    },\n",
    ")\n",
    "\n",
    "# Edges taken after the `action` node is called.\n",
    "workflow.add_conditional_edges(\n",
    "    \"retrieve\",\n",
    "    # Assess agent decision\n",
    "    grade_documents,\n",
    ")\n",
    "workflow.add_edge(\"generate_answer\", END)\n",
    "workflow.add_edge(\"rewrite_question\", \"generate_query_or_respond\")\n",
    "\n",
    "# Compile\n",
    "graph = workflow.compile()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "3443a100",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZIAAAHICAIAAADr9fs8AAAAAXNSR0IArs4c6QAAIABJREFUeJzs3XdcE/cbB/BvSEjCCiMsAdkgCCgi4Kyo4K6LWhy496itA21xb1t33aXuVQdatWodUAXFPdhLNsiSAIEEQubvj/MXKQ1LkhyXPO8/fIW75O5z4Xy4e3K5L0kikSAAACAODbwDAABA60DZAgAQDJQtAADBQNkCABAMlC0AAMFA2QIAEAwF7wDEwCrkc9hCDlvI54n5tWK84zSPTEFkTQ0dBlmHQTEyo2rpkfFOBIDckOC6rSbkpdZmJlRnJ3I7OmvzakQ6DIqhKVUoIEDZotA0uGwhly2sqRIJ+GKSBsneXcfJU5fB1MQ7GgBtBWVLttzUmqd/lZl2pJtZ0+zcdXUYxD5aKc7lZSdyK0r5Wjrk3l8b07ShOQAIDMqWDPfPFvNqxb2/Nja2oOKdRc6Snlc9/avMZ7CRp58B3lkA+EJQtv6lvJh/YUfeuB86mtvQ8M6iQO8eVZbk8oZOM8c7CABfAsrWZ1y28MZvhZNWWCMS3lEULyOW8y6q8tsfrPAOAkCrQdn6pCiH9+jKx4krOuIdRHnyUmse3ygL/tEa7yAAtA60ZhFCiM8T3/ytUK1qFkLI2kXbd7DRvTPFeAcBoHXgaAshhG4dKxoYZKpN8I8Lv0zso0qSBqlrP328gwDQUnC0hWKjKg1MNNWzZiGEPPsbPL1dJhTAXy9AGFC20NNbZb2/ZuKdAk+9RzCf3irDOwUALaXuZSs2qrLvKBMNshp8dti4rv0MqsuFNdUivIMA0CLqXrZSXlZZOGgpc42ZmZlff/31F7zw8uXL69evV0AihBDS0adkxnMUtHAA5Euty1Z1hZDPEyv5Uvjk5GQlv7Al7Nx1spO4ils+AHKk1mUrL7XGxYehoIVXV1fv3Llz9OjRX3311bx5865fv44QOnr06MaNG4uLi729vc+fP48Qevz48Zo1a0aMGNG3b9/58+e/fv0ae/nFixeHDBny6NEjX1/fXbt2zZ0799atW7dv3/b29k5NTZV7WhsX7VqOSCSU+4IBkD+1vnENq6jOwERRh1obN24sKSkJDQ21s7O7fPny9u3b7e3t58+fz+fz79+/f+vWLYQQj8dbs2aNr6/vxo0bEUIRERFLly69fv06k8mkUqlcLjc8PHzTpk2dO3e2traePn26jY0N9kxFEAok7DK+kbmqfQ0TqB61LlvcKqGlo6IaW2/fvp06dWrPnj0RQosXLw4ICDAwaPjtZTqdfvHiRS0tLWyWu7t7eHh4bGysv78/iUTi8XjTpk3z8fFRUMIGdBhkbpXICL6nCNo9NS9bIm2Got4BT0/Pc+fOVVZWenl59erVy9XVVXYGLvfgwYNv3rwpK/t0CUJFRYV0rpubm4Li/ZcOg8KtgrNEQABq3dsiUzTIFEVd+rBhw4ZJkyY9e/Zs2bJlgwYNOnLkiFDYsCgUFxfPnj1bIBBs27bt2bNnz58/b/AEKlV5p2xUmgaCa04BEaj10RaVTuJUCk2tFHKPGgaDMXPmzBkzZsTFxT18+PD48eN6enqTJ0+u/5wHDx7w+fyNGzdqaWk1OM5SPna5wNZdB8cAALSQWpctHQalRjGnRWw2++7du6NHj6bT6Z6enp6enmlpaf/9BJDNZjMYDKxmIYQiIyMVEaaFaqqEOgo7ZQZAjtT6JJFpRhXwFXJeRKFQwsLCfvzxx7i4OBaLdfv27dTUVE9PT4SQtbV1WVnZo0ePcnNznZycysrKrl69KhQKnz59+vLlSwMDg+Ji2bdk6NixY2Ji4qtXr8rLyxWRWZtB0TWAsgUIgLxhwwa8M+CGQtV4/jfLo4/8b35ApVI9PDwePHhw8uTJc+fO5efnz5kzZ8yYMSQSydjYODk5+dSpUwYGBuPHjxeJRBcuXNi/f39FRcXq1atramrOnj1bVlZmYmLy+PHj2bNna2h8+tNiaGj4+PHjP/74o0ePHlZWcr69X1E2LzeZ26Uv3AcCEIC637jm9OacsYusGEbqfpTx9BaLpqXR3d8Q7yAANE+tTxIRQq6+jA+ZtXinwB+bJbBz18U7BQAtou5HGV37GZzenOPqo9fYE27cuLF3716Zs+rq6mg02Z9CbtiwoX///nJL+W9NLFkoFFIosn+n586da+zU8v07jgYJGZnBEIqAGNT9JBEh9Ow2i0pv9PyIy+Wy2WyZs6qqqhgM2V9pNDIyotPpco35WWFhYWOzmqikpqamjVW005tzAr+z0jNU979hgCigbCEkQX8e/jB2kSXeOfCR/ppTUcbvMdQI7yAAtJS697YQQoiE+o4xvrg7H+8cOCjNq4t9XAE1CxALlC2EEDKxpHn6Gdw+UYR3EKUSCSXhBwqClqrXeEVABcBJ4mdFWbx3jyqGz+yAdxBlqCjhXz1YMHODnZrfkBoQEZStf3n/jvPyfnnQEitNmiofh2Yn1Tz96+OklTYkVd5KoLKgbDVUXsx/eKXU3Ibee6QxSeUORIpzeDG3ykws6f3GGuOdBYAvBGVLtncPK2NulfUaxuxgr2Vhr6hLGZSGzxNnJ3FLcnml+XW9RxqrwBYBdQZlqylxj9kZcdWsQr5bL32JWKKjT2EYaRLiHSNTSDXVopoqIbdKVMsV5aXW2LvrOHfTs+msjXc0ANoKylbz+DxxfnptdbmAUyUUCyXcKjmPJ5iWlmZmZvbfWza3BU1LA7szj44+2ciMZuEAh1dAdcCF0c2j0jUcuijw/nn3l/7SvXvgV1+5KG4VAKgS+CQJAEAwULYAAAQDZQsAQDBQtgAABANlCwBAMFC2AAAEA2ULAEAwULYAAAQDZQsAQDBQtgAABANlCwBAMFC2AAAEA2ULAEAwULYAAAQDZQsAQDBQtgAABANlCwBAMFC2AAAEA2ULAEAwULYAAAQDZQsAQDBQtgAABANlCwBAMFC28Kevr6+hAb8IAFoK/rfgj81mi8VivFMAQBhQtgAABANlCwBAMFC2AAAEA2ULAEAwULYAAAQDZQsAQDBQtgAABANlCwBAMFC2AAAEA2ULAEAwULYAAAQDZQsAQDBQtgAABANlCwBAMFC2AAAEQ5JIJHhnUFODBg2i0+kSiaSiokJHR4dGo0kkEiqVeu3aNbyjAdCuUfAOoL6MjIwyMzOxx3V1ddiD4OBgXEMBQABwkoibwMBAOp1ef4qFhcXkyZPxSwQAMUDZwk1gYKClpWX9KX5+fiYmJvglAoAYoGzhRlNTc+zYsTQaDfuxY8eOU6dOxTsUAAQAZQtPgYGBNjY2CCESieTv7w+HWgC0BJQtPFGp1NGjR1OpVGtr66CgILzjAEAMX/JJIo8rLius49WIFJBH7XRxGOxqHd+tW7eqIu2qIg7ecQhPQ4PEMKIYmVM1yCS8swBFafV1W3dPF+en11g6aMPIfqAd0tIjl+TWatI0XH303Hvr4x0HKEQrypZQILl6oKDLV0wrZ20FpwKgrZ78WWLpqNWlLwPvIED+WtHb+vPQB5/BJlCzACH0HWtWkF6b8rIK7yBA/lpatjLiOEYd6CYd6S14LgDtQq+RponPqiTQzVA5LS1bHwvqtHTICg4DgDxRqCQuW8hhC/EOAuSspWWLxxUzjKkKDgOAnJlYaVWx+HinAHLW0rJVxxOLhHC0DQiGxxUiBFdCqBq43BQAQDBQtgAABANlCwBAMFC2AAAEA2ULAEAwULYAAAQDZQsAQDBQtgAABANlCwBAMFC2AAAEA2ULAEAwULYAYcyYFbTv15/xTgHwp3Zla+Omn+78fQPvFACAL6d2ZSstLRnvCACANvmSkXtaKDk5Yd+vPxd8yPPw6DZ18uyjYb/a2zkuXRKKECovZx0+sicxKY7H4/n49Jo6eXbHjjYIoezszJmzxx8+dPrChZNPYh6ZmJgO6D947pzFZDIZIZSUFH/6TFhqapK+gWGvnl9NmzpXR0cHIXT12sULf5xcuiR0/YaVY8YELV4U8uzZ438e3otPeFdVxXZ1cZ8yZXY3T2+E0AB/b4TQzl2bjxzd+9eNR0Kh8PiJw89fPCktLXZ39xw7Oqhnz77NbldNTc3W7Wvevn0pFAoXLVxeVlYa/fifM6eupqQmLVw07fCh064ubtgzJ08Z07u338IFS5vY5AbhMzLSaFTajl8OSle3dl0Iq7zs8MFTTUfas29bbOzr6uoqWxv7YcNGjxn9LUIoKytj1pwJ27fu27Vni4GB4bGwP5pYyOix/lMnz45+8k98/Lsb1/9h6DHu3vvr5l9Xs7Mz7OwcBw4Y/E3gRBKJhBCq5lSfPHX0xfMnFZXlnZw7BwQMGzF8DEJo9dplmhRNGxu7i5fOiMViezvHFSHrHB2dseWfOXvs3v1bZWWlpqbmnl27L10SqqGhgRAaExgwY/p8Nrvy9JkwLS0tH+9e3y0KYTKNEUI5OVk//7I+Ny/b09N76uTZLd71gIpT1NEWj8dbtWapoaHRiWOXZ81ceOjIno8fS7CdXiQSLV0+LzbuzdIlq04cu2RoYLRw0bQPhQXYQM0Iod17tvj7D71/99nq0C2Xr5x7+OgBQqjgQ37IyoW8Ot7BAyc3b9yVlfV+6bK5QqEQG22wpoZ782Z46E+bxo4O4vF4W7evqaur++nHjdu27rO2tl29Zml5OQshdPdODEJoRcjav248QgjtP7Aj/OqFsWPGXzj/l18///UbV0ZFRza7aXv2bcvKfL9v7++X/rhdUJAXEfk3FrsJTWxyg/DDh45+8/YllhZ7G5+/eDJ40Iiml//Tqu8LCws2b9p9+eKdfv38f93/S0pqkvT9PHPu2PigKcuXrWl6IZqamrfu/Ono2GnnjkPaWtoRkXd/2bHR2cnlwrmbs2ctCr964eDh3dgzd+zYmJwUv2RJ6KkT4a6u7nv3bU9KikcIUciUd7Gvsff59KmrRkzjNeuWiUQihNDJU0ev37i8YN6S8Cv3Zs1c+CjqwZXw89L1Xrp0RkND4/qfkadPXk1IjD11+jeEkEAg+DF0sYmJ2akT4fPmfH/x0hkWq6zZ3w5QB4oqW89fPGGzK+fN/cHcvIOzk8uc2d+VlBRjsxISYvPyclaFbu7h29vIiLlg/hKGvsHVqxekr/XrF9DfL0BTU7NrVy+LDpbp6SkIoYiIvzUpmps37rK2trW1tQ9ZvvZ9RtqTmEfYkM48Hm/ChGkB/kOtrKzpdPqxsIvLl63u5undzdN7/rwltbW1CYmxDRLW1dXdu39r0sTpo0Z+o8/QHz5stP/AoWfO/t70dnE4nKioiKCgKZ2cXY2MmIsWLqNQNJsd/aiJTW4QfsCAwdra2v88vIe9ENvAgQOHNPlWxyQkxK5YvtbVxU1f3yB40gwPD8/TZ8KwhSOEfLx7fjsuWHoM2BgSicRg6C9eFOLdvQeFQrlz53qXLt2W/PCToaGRVzefGdPmX79+uaKiHCEUF/+2Xz9/H++epqZmc+csPnTwFJP5aTxtPr9uyuTZJBLJooPljOnzS0qKExJiqznVf1w8PWXy7L59++vp6vX3Cxg7Zvy588cFAgH2KkvLjpODZ+rp6jGZxj7evbDfePTjf0pLSxYtXG5mZm5ra//94pUcTnXTmwDUhKLKVnZ2hq6urr29I/ZjN09vPb1PQz8lJMZqamp6dfPBfiSRSJ5du8fFv5W+1tnZVfpYV1cP21mTkuJcXNz09Q2w6ebmHSwsrOIT3kmf6dLp83/LmhrugYM7xwUNHeDvPWxEX4RQZWVFg4Tp6Sl8Pt/Hu5d0imfX7llZGewqdhPblZeXLRQKXf5fAkgkkqure/Nlq7lNloanUqkB/sMiIv7Gfnz8+J8+vf0Yek2NmpWdnUGn0+3sHKRTnJ1c67fwnJ1cG3lpQ52cO2MPxGJxYlJc/TenWzcfsViMveEeHp6Xr5w7cnTf06fRAoGgk7OruXkH7Gl2do4UyqfOg5WlNUIoNy87Pz9XIBC4urp/juTsyuFwPnzIl/4onaWnx+ByOQihDx/y6XS6dMlMprGpqVkLNwSoNkX1tqo51draOvWnGBgYYg84nGqBQIC1mf47FyGEtTwa4HCqU9OSG7yq4v8nU9h/eOxBSUnxD0tne3XzXbt6W+fOHiQSadCQnjIXiBBa/MOsBtMryln6jEaHBcVO37S1Po+6Vv9xY5rdZGl4hNDXIwKv37jyobCAaWT84mXM2tXbml44i1VGp2vVn6KtrV1bW/N54TRaswkbxODz+QKB4PiJw8dPHK7/BOxo68eVG27eDP/n4b3LV87p6uiOHTt+6pQ5WLWi0z6P7USn0xFCXC6nvLyswSwtLW2EkDQkdlTYQFUVW+vf7y2NBgNHAaTAskWn0fn8fw09wGJ9xB4wmcZaWlpbt+ytP5es0cywQEZMYw8PzxnT59efqM8w+O8zH0U94PP5P/24UUtLS+Zx1qcYxiYIoeXLVltadqw/3dTUvIkY2OFeHb9OOoVbw23syULRpzFjWrXJDg5Orq7uf/99w8nJRUtLu0ePPk3kQQjp6OjweLX1p3BruMb/P2v7MnQ6XVtbe/CgEf36+defbtHBCiHE0GNMDp4ZPGlGYmLc4ycPz547rqurF/TtZKxISZ/M4/GwWqOjo4sQqq0XsqaGixAyMjJuIgODoV+/+EpfBYCiypalZcfKyorycpaRERMh9C72dU3Np13QwcG5trbW1NTc0sIKm1JY9MFA37DJ5SEHe6f7D2537eIlPRbLycmysrL+7zOrqth6egysZiGEGuuyW1la02g07AQWm1JRUS6RSLS1mzp6Mje3QAilpiY5O7lgJ1PJSfE0Oh0hRKPS6h9BcDicsrKPX7bJw4eNvnjpTEFBXoD/MOk5V2M6OXfm8XjvM9KcHDthU1JSEm3rnTN+GQcH52pOtfTNEQgERUUfTE3N2FXsyMi7w4eNptPpHh6eHh6eGRlp6e9TsadlZr1nsyux4o61qOztHR0cnMlkclJSnLS/lpKSqKerZ2Ji2kQAc7MOPB4vKysDazVkZKRL30+g5hTV2+rZoy+ZTD5wcCeXyy34kH/27DHpPtrdy9fXt/euXZtLSorZ7MrrN67MXzDl7t2bTS9w3LhgsVh88PBuHo+Xn5/7W9j+mbPHZ2Vn/PeZ9vZOLFbZzb+uCoXCFy+fvn37Ul/foLS0GCFEo9FMTExfv37+LvY1lUqdPm3embO/JyTE8vn8qOjIkJULm70I28TE1N2967Hjhwo+5JeVfdy7b3s159O4xx072ujp6t35+4ZEIhEKhT/vWC9t57V2kwcOGMJifXzxMmb4sNHNvdPI17e3hYXVnj1bU9OSy8tZx08cTklJHP/tlGZf2LQ5s76LiXl05+8bYrE4ISF20+bQZSHz+Xw+hUw5fSZsw6YfExPjystZ9+/ffp+R6uHuib2KwdDff2BHVXVVVXXVmbO/m5mZd/HoxtBjDAoYfu78iadPo6uqq+7fv/3n9UvjxgXL7AZI9e7tR6VSd+3ZwuPxyso+btoSymj85B2oFUUdbTGZxkuXhB4/cfibbwc7OblMmzr3wMGdFMqnCwW2b91386+rm7aEJicndOxoExAwLDBwQtMLZOgxjh+7dPHi6XkLJufl5bi4uK0IWYsd8jTgP3BIbm7WmbO/79233ce7548rN1y8dObCH6eqq6uWLV0VPGnmyVNHX756+seFWxPGT3VwcL5w8dTbty91dHTdOndZvryZqwQQQqE/bdq3b/ucuRN5PN6A/oP8+gUkJcdjH+SvXbv91/2/DAzwMTY2mTf3h/JylrRb36pN1tbW7t69x8fSErsWHDRRKJQtm3Yf/W3fwkXTqFSqvb3T5k27PDw8m31h0zw8PMOOnj9/4eRvYft5vFq3zl22bN5Do9FoNNqmDTsPHNqJtQXt7Bzmz1sybOgo7FX2do62tg5B44fV1dV1MLfYsmkPds3dooXLNTQ0Nm9dJRQKLSysJk2cMXHCtKYD6Orqbtu6Lyxs/9ej/Oh0+tw530dE/t3GjQKqgdTsp2CYu2dKOthr23votXzRHwoL9PQY2KdgEonk61F+M6cv+OabiW1I2x7t+/XnuPi3J49fluMy+Xz+t+OHzZ2zGLuMkyjWb1jJ4VTv3nUE7yCf3T/zoecwI0tHrRY8FxCGoo622OzKhYumOTo4z5q1yNDQ6PjxQxokjf79BylodSqjuLjoQ2H+tT8v2tjYteQMEQA1pKiypa9v8PO2X38/dnDd+hB+XZ2rq/uhg6ewb2y0cwkJsatWL2ls7rmz16XXjilC5D93jx0/5OLitmHdL9LLAuQSCd/tAkCOFHiSSFxFxYWNzepgbqHcLJ/IJVI73C5Fg5NElaTAr1ITVzv8PyyXSO1wuwD4Amp34xoAANFB2QIAEAyULQAAwUDZAgAQDJQtAADBQNkCABAMlC0AAMFA2QIAEAyULQAAwbS0bOnqkzU0ZNw5F4D2TJtBoVDhb7OqaelvVM+QUppf24InAtCO5CRxjDtQW/BEQCQtLVu2nXWqy4UKDgOAPJXm8xy66JI14SxB1bS0bOkbazp104kKL1ZwHgDkg8cVPb5W7D++qdvVA4Jq6Y1rMGlvOAkxbFs3XaYFXRNaBqD9IWmgqjIBly2MjWJNWWVD04K9VAW1rmwhhErz65KeV3EqBewygcJSKYpAIGSzKw0NjcjkdrQ3czhcGo2mqalGNxEqKSkVi8X/nd6hQ1OjvbWEHlNTg4Qs7LS6BzQzFhQgrlaXLYLKzMx0cHC4dOmSl5eXk5MT3nH+ZenSpYGBgV999RXeQZTnypUrp06dKikpqT9RX18/MlL26HAA1EfesGED3hkUi8vlzp49m8FguLm5ubu7M5lMvBM1ZGZmZm9vr6Oj04Lnqgg3NzcDA4Pk5GQu9/OIrWKxWCwW6+joGBsT4ObdAEeqfLT1/Pnz7t27l5aWstnszp074x0HNBQREXHgwIEPHz4ghEQi0R9//BEdHR0dHV1ZWdmvX79+/fr17NkT74ygPVLZsrVz587c3NwDBw5IB5Jot86cOePr6+viImPMR5X35MmT7du3l5SUUKnUp0+fYhOLi4ux+hUbG+vn5/fVV1/179+fTqfjHRa0F6pWtl6/fl1eXj548GCsmYV3nBZRw95Wfa9fv16/fj2ZTL55s+Ew3TweLyoq6vHjx1FRUV26dMHql7l5W9v2gOhUqmy9efPm999/37hxo5mZGd5ZWuHdu3dWVlYmJiZ4B2nXXrx4gdUvBoPRr18/Pz8/9Tw+BSpStlJSUs6ePbtt27bKykoDAxjsT8WlpaVhp5Dl5eVY/YIWmLohdtmqqqpiMBghISFTpkzp2rUr3nG+kDr3ttqipKQEq19v377F6pefn5+WFgyJqPqIWrbKyso2bdo0ffp0Ly8vvLO0lZr3ttqurq4Oq1+PHj3y8PDASliHDh3wzgUUhXhlKzc318bG5s6dOwYGBr1798Y7jhxAb0uOXr58+fjx40ePHunp6fn5+fXr18/V1RXvUEDOiFS2JBJJSEgIk8lctWoV3llAe5eenh4dHR0VFcVisb766is/Pz/V+CMHCFO2MjMztbS0TExMnj171q9fP7zjyBn0thSqtLQU+wjy5cuXfv+nVt9JUD0EKFvh4eHh4eHHjh3T1dXFO4tCQG9LOYRCYVRUVFRUVHR0dKdOnbD6ZWlpiXcu0Grtt2zl5ua+efMmMDAwLS2tU6dOeMdRIOhtKd+bN2+w+kWn07EWmJubG96hQEu1x7IlkUhKS0sXLVq0adMm+C4hUKjMzEysfhUXF2MfQfbp0wfvUKAZ7atssVis/fv3h4aGCoVCVT0l/C/obbUHLBYLO4V88eKF9Cow9dkJiaW9lC0Oh6Orq7tu3boePXqMGDEC7zhKBb2tdkUkEkX9n7OzM1a/rKys8M4FPsO/bNXV1e3YsaNz587ffPMNvknwAr2tduvt27dY/aJSqVgLzMPDA+9QANeyhX2F8NmzZx8/fhw1ahReMQBoVlZWFtYC+/DhA1a/4OgYR7iVrSNHjkRFRV28eBGXtbcr0NsikPLycqx+xcTEYPXLz8+PwWDgnUu9KLtssdnsoqIiFxeXv//+e9iwYcpcdbsFvS0iEovFWP2KiopycHDA6pe1tTXeudSCUsvW69evf/rpp5MnT3bs2FFpK23/oLdFdO/evcPqF5lMxupXly5d8A6lypRRtrhc7u3bt4OCglT+wlGg5rKzs7H6lZeXh30EqXrfRWsPFFu2sLHwBgwYsHr16sGDBytuRYQGvS3VU1lZiX0E+fjxY+lVYPr6+njnUhGKKlsikejw4cODBw92dnZu/4NQtJFQKKytrf3il0dGRnbq1KktVwZpa2uTyeQvfjlQKOkXIW1tbbESZmNjg3coYpN/2ZJIJCQSaefOnWZmZlOnTpXvwtsnHo/H4XC++OUCgYBMJmtofPlA2Xp6ejQa7YtfDpQjLi4Oq18IIax+EfeWvPiSc9k6cuRIWVnZ2rVr5bjM9q+NZavtoGwRS25uLla/cnJypKeQeIciErmVrbq6uuLi4oiIiFmzZsllgQTSxrJVU1NDpVIpFMoXLwHKFkGx2WzpKSR2L0M/Pz8YxqVZcihb9+7dW7NmTUxMDJVKlVMqgmlj2WKz2VpaWm1596BsqQDsI8ioqChra2usftna2uIdqp1qU9mKi4vr2rXr7du3hw8frvJ99yYoore1detWDoezffv2liwBypYqiY+Px+qXWCzGLqHo1q0b3qHaly9sAxcUFPTq1UsoFCKERowYoc41S6abN2/u2rWrhU/W1NRsSz8eqJguXbosXrw4PDx83759RkZGhw8fHjhw4MaNGx8+fIhdUQRa/b/l8uXL2PUN0dHR3bt3V0wqwnv//n3Ln1xTU4P9AQCgPmtr6ylTpvz+++/Xr1/38vK6c+dOz549ly5d+ueff5aXl+OdDk+tawMHBwdjH3nAhSdNWLFiRUJCAkIoIiLi4MGDjo6Oz549O3fuXH5+PoPBcHBwWLQWVgfpAAAgAElEQVRokampKfbkZ8+enT59urCw8L+zpF6+fBkeHp6enm5oaOjm5jZz5kwjIyM8tgzgg8FgjBw5cuTIkQihx48fR0dHHzlyxNLSEvsU0t7eHu+Aytai3tbFixeNjY0DAgJqa2th1N//+m9va8mSJVZWViEhIdg9m9asWTNnzpyBAwd++PDhwIEDJiYmmzZtks6aOXOmv79/UVFR/VnS3lZGRsZ33303derUgICA3NzckydPGhoabt26tf7qoLelhhISErAuvkAgwOqXCgx13ELNH22Fh4cXFBRg9/CDmvUFzpw506dPn7FjxyKE9PX1586dGxoamp6e7uzsjM0aN24cQsjQ0LD+LOnLk5KS6HT6hAkTNDQ0TE1NnZ2dc3JycN0g0C54eHh4eHgsWrQoPz8/Ojr66NGj6enp0hHVVPtbE432tsLDw7///nuE0OjRo0NCQjQ1NZUbTHVkZ2fX/wI5VpLS0tKks6S9rfqzpNzc3Hg83rp1665du/bhwwd9fX24tBrU17Fjx+Dg4LCwsFu3bvn6+t69e7dPnz4//PDDtWvX+Hw+3ukUotGylZGRsW3bNuxzLuVGUilcLreurq7+GRx2xFpTUyOdJRaLsU+IpLPqL8HR0XHz5s1MJvPEiROzZs0KDQ1NSkrCY1NAe6erqztixIgdO3Y8f/48KCjozZs3WMNB9TRatn766ScYtqTtsILF4/GkU7CqZGRkJJ1Fo9GwS+SlsxosxMfHZ+nSpadPn16+fHlVVdX69evhk0fQtD59+kyePDk3NxfvIAohu2xFRkZGREQoPYwKolAoTk5OKSkp0inJyckIITs7O+ks6XVb0ln1lxAfH//q1SuEEJPJHDRo0Pz58zkcTklJCR5bA0C7ILtsZWZmZmVlKT2M6rCwsEhNTY2Nja2oqBg1atTTp0+vX79eXV0dFxcXFhbm6enp6OiIEMJmXb58uaKiosEsqeTk5K1bt965c6eysjI1NfXGjRtMJtPMzAy/jQMAZ7I/SfT398d9IDJCGz58+Pv371etWrVly5aAgAAWixUeHn706FFTU1MvL68ZM2ZgT8NmXb9+/cSJEw1mSQUGBlZWVh49enT//v3YsFc7duxoy/euASA6/MdJVAFwvy3QDqWkpGzbtu3s2bN4B5E/2X+0IyMjJRJJQECA0vOoI/isFoBWkV22MjMzlZ5EfbX9flsAqBXobeFPIBBAzQKg5WT/b3FwcFB6EvUFA1gA0CrQ28If9LYAaBXobeEPelsAtAr0tuSATqe35Yjp119/HTZsWI8ePb54CXBzVKBWoLclH21pTgUGBlpZWUF7C4AWgt4W/mCAAwBaBb6TiL8zZ86kpqbinQIAwoDeFv7evXtnZ2fn4uKCdxAAiAF6W/ibOnWqlZUV3ikAIAzobeEPelsAtAr0tvAHvS0AWgV6W/iD3hYArQK9LfxBbwuAVoHeFv6gtwVAq0BvC3/Q2wKgVWQfbQ0aNAh6W0oDvS0AWkV22Wow5hVQKOhtAdAqsstWRESERCIZNGiQ0vOoI+htAdAqsntbWVlZ2dnZSg+jpqC3BUCrQG8Lf9DbAqBVoLeFm0GDBmH32BIKhcnJySQSCSGkq6sbHh6OdzQA2jXobeFGT08vLy+v/hSRSNS3b1/8EgFADNDbwo2/v3+DKba2tsHBwTjFAYAwoLeFmwkTJjx8+DAnJ0c6pXv37nB6DkCzZB9t2dnZ2dvbKz2MemEymf7+/lhLCyHUsWPHiRMn4h0KAAKQXbYiIiIePHig9DBqJygoyNraGnvs4+MD32AHoCWgt4UnJpMZEBBAIpE6dOgwfvx4vOMAQAzQ25JBUCeprhAoZ12D+wc+vPfK09PTUKdjeTFfGavUQEamVGWsCADFgOu2/iUznhsXXVlawDO2oNfViJSz0tE9NyCE/j5VrJzVGZhSc1O4zl56foEmmjSSclYKgBzBdVufpbyoTnvH6T3KTEdfxce1FwklrMK6Y+uyZqyzo+vAiNaAYKC39Unyi6qMeK7/xA4qX7MQQmQKydSaHhzqcGwt3FUNEA/0thBCSCxEqa+qB02xxDuIUpFIqP+35jF/sfqMZOKdBYBWgOu2EELoY2Edv06Mdwoc6BlR81K5eKcAoHXgui2EEGKzBOZ2WninwIGBKVWTRsY7BQCtI/skUd1uJC8SinkcdTzakoglH/N5eKcAoHWgtwUAIBi4bgsAQDDQ2wIAEAz0tgAABAO9LQAAwUBvCwBAMNDbAgAQDPS2AAAEA70tAADBQG8LAEAw0NsCABAM9LZwtn7DSg6neveuI3gHAYAwoLelcNnZmaGrf7h44ZbMuf36+QsESrmFPACqAnpbCpeWntzEXP+BQ5SYBQBVAL2tL7R+w8pNm0N/C9s/wN87+vE/CKGkpPiVP343avSAKdMCDx/Zy+VyEUInTx39ZcfGkpLiAf7eV8LPZ2VlDPD3fv78ybigobPnTsSWszxkAbbM8nLWlq2rJ0z6ekxgwNbta/PzcxFCr14/H+DvnZgYJ111SmrSAH/v5y9iGlspAKoN7iX/hTQ1NbOyM7KyM7Zu3tPFo1vBh/yQlQt5dbyDB05u3rgrK+v90mVzhULhjOnzJ4yfamZm/jDy9bfjgjU1NRFCZ84dGx80ZfmyNfUXKBKJli6fFxv3ZumSVSeOXTI0MFq4aNqHwgKvbj56unpYZcQ8efJQT1fPx7tnYyvF4/0AQHlkl61BgwYFBAQoPQyRkEik4uLCjet39O7dz8DAMCLib02K5uaNu6ytbW1t7UOWr32fkfYk5tF/X4UQ8vHu+e24YFcXt/qzEhJi8/JyVoVu7uHb28iIuWD+Eoa+wdWrF8hk8oABg6MfR0qfGf34H3//oWQyuYUrBUDFwL3kv5yNtR2dTsceJyXFubi46esbYD+am3ewsLCKT3gn84XOTq7/nZiQGKupqenVzQf7kUQieXbtHhf/FiHUv/+gkpLi9PepWIO/oCDPf+DQ1q4UqCFtbW28IygEjJP45ag0mvQxh1OdmpY8wN+7/hMqylnNvrD+EgQCQYMlGBgYIoQ8u3Y3NDSKjo50dnJ5/OShiYmpu3vX1q4UqKGamhq8IygEXLclH0ZMYw8PzxnT59efqM8waPkSmExjLS2trVv21p9I1iBjR14DBgx+EvNo9qxFT548HBQwXF4rBYCI4Lot+XCwd7r/4HbXLl4aGp/Ou3NysqysrFuxBAfn2tpaU1NzSwsrbEph0QcDfUPs8cD+g69du/j8+ZP3GWmrQjfLa6UAEBH0tuRj3LhgsVh88PBuHo+Xn5/7W9j+mbPHZ2VnIISsrKxZrLInTx5hFzQ0pruXr69v7127NpeUFLPZlddvXJm/YMrduzexuW5uXUxNzU6eOmpv72hra9/sSgFQYXDdlnww9BjHj13SomvNWzB56vRvYuPerAhZ6+zkghDq2aOvh7vn2vUhkf/ca3oh27fu8/ML2LQldExgwLU/LwYEDAsMnCCd299vUPr71IEDPl+e2sRKAVBhJJkng2FhYQihuXPn4hEJBymvqnJTeH1Gm+IdRNlEQskfP2ct2OmAdxAgfykpKdu2bTt79izeQeQPelsAAIKB7yQCAAgGelsAAIKB67YAAAQDvS0AAMFAbwsAQDDQ2wIAEAz0tgAABAO9LQAAwUBvCwBAMNDbAgAQDPS2AAAEA70tAADBQG8LIYTImhpaurLPl1UbCZHMbel4pwCgdaC3hRBCRqbUgveqedftprGKeR9Ly8+cOYN3EABaAcZJRAghYwuqli5FrH4DDFaxBF16dqisrHz9+jXeWQBoKRgn8ZPu/gZ3TxfgnUKpyovq3v3D6jnM+Pvvv/fy8kIIDR069Pr163jnAqAZcC/5T2xctPuPM7lxJK84h1dbLcI7jmJVlPCz4qsjLhROX2+LTcEG0bh58yaXy0UIZWZm4p0RgEbBOImfmVnThk83fx1RUfC+RoOiwWUL8E6kEOa2WnU1IgcPnVmbGn7wQqVSg4ODEUJisdjHx+fEiRMeHh44xQSgUXDd1r8YmVMHTzZDCIlFCJEUtZZx48bt2bPH2hqfkcE0Gj3I/szJyenly5dJSUnYIdjIkSNJJIW9HQC0Ely3JZsGWVFLFggE48YF2tq299EMSSSSu7s79sDX1/fFixckEgmKF2gPoLelbJqampMmTcI7RSuMHDny1atXJBIpIyPjwIEDQqH6feAK2hm4bkvZXr169fjxY7xTtBqJRHJycmIwGLt378aOGfFOBNQX9LaU7erVq8S9uGTatGnYgz179tDp9MWLF2MfQQKgTHDdlrL5+/v36tUL7xRt9eOPPxoZGWVlZYnFYjabjXccoF6gt6VsgwYN0tHRwTuFHEyZMsXR0ZFEIgUGBp4/fx7vOECNQG9LqbKysk6dOoV3CnkikUiRkZHm5uYIoTdv3lRUVOCdCKg++E6iUkVHR3M4HLxTyJ+/vz9CSE9PLygoCLvaCwDFgeu2lMrHx8fMzAzvFIri7Oz84MGDvLw8hNDRo0fHjRtnbGyMdyiggqC3pVRubm4q/z8Zu/rfyclp4cKFCCE+n493IqBqoLelPFwuNzQ0FO8USuLv73/58mWEUHJy8qZNm6qrq/FOBFQH9LaUJyEhQQ3/93p6enp6el67dg0hxGKx8I4DVAH0tpTHzs5u9erVeKfAwahRo7AHJ06cYLPZGzduJJMV9p1PoAbgXvLKo8LN+BZasWLF3bt3KysraTRaWVmZra0t3okAIUFvS3mWL19eVlaGdwqcDR06lMlkampqhoSEwD3swZeB3paSVFRUxMfHq/zHiC1Eo9HCw8O7dOmCELp37156ejreiQCRwHcSlYROp587dw7vFO2Lp6cndrXXhg0b0tLS8I4DCAOu21ISLS0t6G3JZGdnd+HCBRMTE4TQ2rVr4Tb2oFnQ21KSbdu2PX/+HO8U7ZeRkRFCaMSIEYcOHUIIwV0lQBOgt6UkT58+hc9nm9WzZ889e/YghNLS0hYvXvzx40e8E4H2CK7bUgaJRHL+/Hl9fX28gxCGr6+vSCR6+/btkCFDMjIyHB0d8U4E2hG4bksZSCQS1KzWkt5M8c8//8zMzDx8+DDcSRVgYJxEZThx4oREIpk1axbeQQhpxYoVr1+/FovFRUVFRUVF3t7eeCcCOJP95+vjx4/QVpCjsrIyNzc3vFMQmLe3N4VCYTKZx44du3jxIt5xiIFMJqvqaZPso62ePXtCb0uOQkJCYITBtqPT6UePHs3JyUEIhYeHDxw4EPv8EciUmJhIp9PxTqEQcN2WMmhoaEDZkhfsm4xOTk4TJkzgcrl4x2m/UlJSXF1d8U6hEHDdljKEhIQ8efIE7xQqpWvXrvfv30cIFRQUwAAcMqWkpHTu3BnvFAoB120pg0gkgpNuRdDR0bGysiotLcWu9gJSYrE4PT29U6dOeAdRCJLM/07Z2dkSiQTOEwFRVFdX6+np/f77715eXt27d8c7Dv6SkpJ27Nhx+vRpvIMoBPS2gCrQ09NDCA0fPjwsLKy8vFwkEuGdCGcq3NiC3paSLF269PHjx3inUH2Wlpa//fabjo4Oi8Xavn27UCjEOxFuVLixBb0toIJoNJqpqamzs/OOHTvwzoKblJQUFxcXvFMoCvS2gIrbvn27i4vL2LFj8Q6iPCKRqE+fPip8xxHobQEVt2zZsuTk5OLi4rq6OryzKElycrIKN7agt6Uk0NvCEY1GW716tbGxMY/Hmzt3bmFhId6JFE61G1vQ2wLqgkKh6Ovrz58//+bNm9hQu3gnUiDVbmxBbwuoqX379kkkkqVLl+IdRCEmTJiwdetWBwcHvIMoCvS2gDpasmSJqalpQUFBTU0N3lnkjM/n5+XlqXDNarRs3b9//969e0oPo7Kgt9UOBQcHW1lZicXioUOHxsXF4R1HblT7QlOM7LKVk5OTm5ur9DAAKJuuru65c+ew4c5UY59Xh7Ilu7eF3dIIxjoHauXChQsvXrzYtWuXpqYm3lm+3Pr163v06DF8+HC8gyiQ7NsEQsGSi1GjRn348EH6h4FEIgmFwoEDB+7duxfvaECGSZMm2djYlJaWGhgYSCQSXV3d+nPHjBlz/fp1/NK1VEpKyrRp0/BOoVjQ21KgXr16SSQSjf8jkUjm5uYqv0sRWp8+fSwtLSkUytdffx0REVF/Vk5Ozpw5c/CL1iJ1dXWFhYUq/3ka9LYUCPvrXX+Ku7s7NoI8aM9oNNqjR4+wgYLevXuHEBo6dCiFQklOTj5y5Aje6Zqi8tfHY2SXrcGDBw8ePFjpYVSNjY1Nz549pT8ymcypU6fimgi0wsCBAxFCJSUlY8aMKSkpwY5l7ty5Exsbi3e0Rqn89fEY2WXL1tYW2ltyERQUZGlpiT328PDo2rUr3olA6wwdOrSiooJMJmM/FhYWbtu2De9QjVL56+Mx0NtSLDs7uz59+mCHWpMnT8Y7DvgS1dXV0sckEik7O3v79u24JmqUWh9tQW9LjiZMmGBqaurh4aGCXS01uD++r68vQkgikYjFYuxfkUgUGRnZDq8frqmpKS0tbdBOVUnt5bqtoizeu0eVJXk8bpX63pGScDrYavFqRbauOn1GMfHO0rw3/1RmxlWTKRpF2bV4ZwEykDSQlg7Z3FbLa6CBuU1TIzzKLltKlhHHffuwwrMf08CMqqVLxjsOaIXKUj67jP/4z5LZm+01ae13LMjL+wpsO+sZW9KMLegk2ecYAH+11aLKUv67RyzfIUZ2btqNPU122bp//75EIhkyZIiCQyKEUOJTdmZCzcAJHZSwLqAgIqHk3NbM7/Y44h1Etkt78jv3MrLtrIN3ENBSEecLXbx1XX0ZMufi3NuqrRZnxnOhZhEdmUIaNNnyUfhHvIPIEP+YbeOqCzWLWAKCLdLecOpqxDLn4nzdVlFuLUmj/Z5ZgJZjdqBmxFa34InKlpvKZTCpeKcArUdCRTk8mXNw/k5iVbnAzEZLOesCCkXTJptaa3EqhboGsncq/JCMzGl4ZwCtZm6jXVnGR0hGh0v2Hqa03ha/VsyXXU8B8bAK2+MYE+0zFWiWoE5MbuTzOdllC7sAAgAA2iHZZQu+kAgAaLfgflsAAIKB7yQCAAgGelsAAIKB3hYAgGCgtwUAIBjobQEACAZ6WwAAgoHeFgCAYKC3BQAgGOhtAQAIBu4lD4DyZGVlDPD3jo9/h3eQL9ceNgHGSZSPjZt+uvP3DbxTgPbOwMBw6pTZpqbmCKHs7MwJk77GO1GL1I9afxPwAr0t+UhLS/bx6YV3CtDeGRkxZ0yfjz1OS0/GO05L1Y9afxPwQrzeVkVF+cofvxsxst+ChVPv3vvr2PFD02aMw2YJhcLfwvbPmBU0YmS/H0O/f/78CTY9OztzgL93SmrS2nUhA/y9gyYMP3J0n0gkwuaWl7O2bF09YdLXYwIDtm5fm5//6ez46rWL33w75EnMI/9BvgcO7cKW8+v+X6bNGDdkWO958yffuBmOPXOAv3dRceHOXZtHju6PTbl776+F300fNqLvwu+mh1+90JJxRhpbOEJoTGDAjZvhZ84e8x/k+/Uov42bfmKxyrBZz1/ELF02b9iIvsFTxmz/ZT2LVZaXlzPA3zsu7i32hIjIuwP8vf+8fhn7EZubnJKIEEpKil/543ejRg+YMi3w8JG9XC4Xe876DSs3bQ79LWz/AH/vJzGP2vwbI5j//t5l7lctfJ8bLE16hnXy1NFfdmwsKSke4O99Jfx8E/th0yL/uTd5ypgB/t4Lv5teVFw4wN87IvIuQujipTPDRvSVPg1bUUxMFPZjY/tnNad6/8GdwZNHD//6q6XL5t2+cx0h1CBqg5PEmJioufOChwzrHTRh+Ko1S0tKirHpTey0bUe83taOXZvy8nN27ji8ZfOeFy9iXryI0dD4tBX7D+wIv3ph7JjxF87/5dfPf/3GlVHRkQghTU1NhNDuPVv8/Yfev/tsdeiWy1fOPXz0ACEkEomWLp8XG/dm6ZJVJ45dMjQwWrho2ofCAoQQlUqtqeHevBke+tOmsaODEEKHDu9+9erZD9//+PP2/cOHj/l1/y/PX8QghO7eiUEIrQhZ+9eNR9ge/MuOjc5OLhfO3Zw9a1H41QsHD+9udrsaWziW/9KlMxoaGtf/jDx98mpCYuyp078hhNLfp4au+qFbN59TJ8K/X7wyMzP9lx0brK1tTU3NkpLjsdcmJsaamZkn///HhMRYXR1dl06dCz7kh6xcyKvjHTxwcvPGXVlZ75cumysUCrHVZWVnZGVnbN28x91N7YbR/u/vXeZ+1cL3+b9Lw8yYPn/C+KlmZuYPI19/Oy64if2wCXl5OVu3rfH3H3rj+j8zZyzYtn0tQohCaebusk3snzt2bExOil+yJPTUiXBXV/e9+7YnJcU3iFp/Ua/fvFi3YcXgwSMuX7yzfu3PJSVF+/b/jM1qbKeVC4Jdt8VmVz5//mTxdys6u7ojhJYvWzNx0tfGJqYIobq6unv3b02aOH3UyG8QQsOHjU5MjDtz9ne/fv7Ya/36BfT3C0AIde3qZdHBMj09JcB/aEJCbF5ezu5dR7y6+SCEFsxfEvM06urVC98vXkkikXg83oQJ07BZCKG1a7fX1HA7mFsghLp5et+9e/Plq6c9e/RpEPLOnetdunRb8sNPCCFDQ6MZ0+bv2LVp8qSZhoZGTWxa0wu3tOw4OXgmQgjp6vl490pPT0EIJSbE0un0ycEzNTQ0zMzMXTp1zsrOQAh18/RJSUnEXhgX/3bokJHSvltCQqy3d08NDY2IiL81KZqbN+7S1zdACIUsXzsxeOSTmEf9/QJIJFJxceHRw2fp9KbGqlNVDX7vTexXLXmfGywtKytD5kqb2A+biHrv/i0DA8OpU+aQyWTv7j3KWWWJiXHNbmAT+2dc/NsJ46f6ePdECM2ds9jPL0CfYdDEok6cPNLvq4HjvpmEENLXN1i4YFnIioWpackunTo3ttPKheyjLVtb2/bZ3srMeo8Qcnf/dAigq6vr5eWLPU5PT+Hz+T7enxtMnl27Z2VlsKvY2I/Ozq7SWbq6ehxONfZXUVNTU1qYSCSSZ9fucfFvpc906eT2efUSybVrF6dO/2aAv/cAf+/UtOTKivIGCcVicWJSXP0Y3br5iMXi+ITmPnlpcuH1w+vpMbhcDkLI3cOTx+OFrl5yJfx8wYd8fX2Dbp7eCCGvbj7Y6tjsypycrFEjx7FYZdjRe0JiLPaOJSXFubi4YTULIWRu3sHCwkoa0sbaTj1rlpT0997EftWS97nB0hrT7H4oU0ZGWqdOncn/v3Wxm3tXbADtJl7S9P7p4eF5+cq5I0f3PX0aLRAIOjm7mps3NapWVtZ7F5fPm9bJuTNCKDU1CftR5k4rFzjfS761qqurEEI6OrrSKQyGPvYAK0OLf5jV4CUV5SzssFl6Llkfh1MtEAgG+HvXn2hgYCh9TKV+GvRFLBb/tOoHgYA/Z/Z3np7eerp6/10XQojP5wsEguMnDh8/cfhfMf5T4OprduEkkozxjZydXH7evj86OjLs9wOHj+zt7uU7fdo8d/eu3bv3qKpi5+XlZGVnODl2MjJidu7sER//1te3d2Fhga9Pb2zDU9OSG2x4RTnr01bT1H3MCOnvvYn9qiXvc4OlNabZ/VCmysoKS8uO0h+16M2PJtP0/vnjyg03b4b/8/De5SvndHV0x44dP3XKnMbOOjkcTl1dHY32+c+btrY2Qqim5lOTVOZOKxcE+04i9h4J+HzplIrKT+WAaWyCEFq+bHX9XyRCyNTUvLy80V4gk2mspaW1dcve+hPJGjLuvJ/+PjU1NWnXzsPd//9XlMOpNjE2bfA0Op2ura09eNCIfv8/OcVYdLBqYrtauPD/6uHbu4dv7xnT57958+LqtT9WrV5y7eoDJtPYzs4hKTk+IzPdo0s3hFAXj25JyfEaZLJFB0szM3OEkBHT2MPDs8FHQk2fEainJvYrbW3tZt/nlq6lxfthfXp6jDr+5wE+amprGnumSPzpA6im90+GHmNy8MzgSTMSE+MeP3l49txxXV29oG8ny1wmdjzO49VKp3BruAghppFxc5vbVgTrbXXsaIMQys7JtLW1x+r927cvzcw6IISsLK1pNBrWGMKeXFFRLpFItLW1yxs/0HFwcK6trTU1Nbe0+FRWCos+GOjL+CvHZlcihKSlJCcnKycny87WQeYyqznV0hgCgaCo6IOpqVkT29XyhdcXG/umjl/Xw7e3sbHJkCFfm5tbLFk2t7ikyMqyY7duPnFxb7Oy3k+ePAsh5OHuGXbsgFAo9Pbu+SmkvdP9B7e7dvGSHoTm5GRZWVk3vUY11MR+hZ1hNf0+t1DL98P6zM0tXryMEYvF2C8xLu6NdJamJrWurk4oFGLHSnm52fXXJXP/ZFexIyPvDh82mk6ne3h4enh4ZmSkpb9PbWztFAqlk7NrUlK8dAr22N7BqVXb/gUI1tuytLCysbE7fSbsQ2EBh8PZ9+v2Dh0ssVna2trTp807c/b3hIRYPp8fFR0ZsnLhvl9/bnqB3b18fX1779q1uaSkmM2uvH7jyvwFU+7evfnfZ9ra2FMolEuXz1ZVV+Xl5Rw4uNPHu2dxSRFCiEajmZiYvn79/F3sa6FQOGfWdzExj+78fUMsFickxG7aHLosZD6/3hFiqxbehMSkuA0bV/5161plZUVySuK1Py8aG5uYm3VACHl5+sTFvcnITPdw90QIubt75uZmv3nzQtpwGTcuWCwWHzy8m8fj5efn/ha2f+bs8VhHH9TX9H7V7PvcBCsraxar7MmTR/n5uS3fD+vz8wsoK/t4+MheoVD4/PmTy1fOSWd17uwhkUju3vsLu/rhwsVT0lmN7Z8UMuX0mbANm35MTIwrL2fdv3/7fUYqtl31o9YPMHbM+Ccxj65e/aOquupd7OvDR/Z4dfNxcp6frvEAAA/iSURBVOzU+re5dQjW20IIrQxZt2vPlilTxzrYOw0aNFxHR1f6ac6E8VMdHJwvXDz19u1LHR1dt85dli9f0+wCt2/dd/Ovq5u2hCYnJ3TsaBMQMCwwcMJ/n2ZmZr561ZbTZ8JGjxloadlxdehmVnnZ2nUh02aMO30yPHjSzJOnjr589fSPC7c8PDzDjp4/f+Hkb2H7ebxat85dtmzeQ2uyW9T0wht7VdC3kysrKw4e2rVn7zYqlTpwwJC9e8Kwv65eXr7FJUXW1rbYx5e6urq2tvZZWRnd/t/0Zegxjh+7dPHi6XkLJufl5bi4uK0IWevs5NKC34DaaWK/avZ9bkLPHn093D3Xrg+ZNnXu9GlzW7gf1ufj3XPe3O//+uvq1Wt/6OroLl++ZuOmn7BZri5uC+YvCQvbv3vP1s6dPebOXrxk2VysW9/Y/kmj0TZt2Hng0E6skWdn5zB/3pJhQ0c1iNrvq4HSAIMHj/hYVnrpytmDh3ebmZl7d+85Z/Z3bXuzW4Qk83OHsLAwhNDcuXMVvfqX98rreMizf1NXBjTAZlfyeDxp4yB09RIKmbJ50y6FZQQtFb4359slVu1tVOpTG3OGzrDS0W9fqRShsrJi7DeD1q3dPqD/ILyzyEHsw3K6NvIZLKM4EKy3hX37r7i4cMGCpV08ut386+qbNy8aNDIBAKqNeN9JXL/+l527Nv1+7ODHjyU21nbr1/7s08r2J15Gjurf2Kwff9zQt0+jc4HaCl29JDEhVuas4cPHLJi/ROmJ2gXi9bb0GfpbNjX/XZl26MKFvxqb1ZIrboAaWrt6m/TahQY0KZoNphgYGD6MfK2UXDgj2HVbhKanq4d3BEAw2GUWoAHi9bYAAGqOeL0tAICaI979tgAAag56WwAAgoHeFgCAYKC3BQAgGOhtAQAIBnpbAACCwbm3pUkliSWKugUiUDJDcypqf79NA1OqzBvbgnaOQtPQbOS2KTjfb0tHn1JexFPCioCiCQWSouxaXcNmbsipfBKJpLKsrgVPBO0Lq5Cn28h9O3DubRlb0FDzQwgCAqgq49u767bgicpm5ahVXSHAOwVoNRJWH2TBeZxEI3OqvrHmmwiWEtYFFOrh5aJew1tx3zSl8Rls9DayjFcrxjsIaIWXd8uYHagGpg2/Lo6RfZtArCWvtMsgYv5i1VaLu/Y3ouu0u1MM0KwqliDiQuGouRaGjexkuKvjiU9tzB44wcK0o1Zzw0oAnPG4oncPy/WNKT2GNHorfdllS/nioisTnlTx+WKVrFxisViDpIHaXbe6rQyMNbOTOPbuuj2HGRmaNTOmFr4kYvTP5dLU11W2nXXZLDhnbI80NBC3UkjXIXfpq+/RV7+JZ8ouW7jcb0siQbUcEbdKqMyVKseuXbsGDhzo5eWFdxA50yAhQzMasY5fyksEIiGcMLZHJIS0GRQtXXKz4yu2o+u2SCSkrUfW1iPUf4KW4aMybQOhiaW6j5naHhiZtdMzWdBy8J1EAADBwHcSAQAEA99JBAAQTDvqbQEAQEtAbwsAQDDQ2wIAEAz0tgAABAO9LQAAwUBvCwBAMNDbAgAQDPS2AAAEA70tAADBQG8LAEAw0NsCABAM9LYAAAQDvS0AAMFAbwsAQDDQ2wIAEAz0tgAABAO9LQAAwUBvCwBAMNDbAgAQjOzeVnp6+q+//qr0MCpLIBAwmUy8UwCgImSXLWdnZ5FIlJycrPQ8qqaioiIoKCgwMLBz5854ZwFARcgelRrDYrHEYnFlZaWTk5NyU6mIyMjIn3/++bfffrO3t8c7CwCqQ/bRFobJZBobG69btw4Ou77Azp0779+//+DBA6hZAMhXU2ULIUQikf744w82m62sPKqgqqpqwoQJNjY2v/zyC95ZAFBBzZQtTK9evRBC3377bXFxseIjEdvDhw/HjBmzZcuWoKAgvLMAoJpaVLYwJ06cOHfunCLDEN7u3bvv3Lnzzz//ODo64p0FAJXVirKlp6cXEhKCEDp58qQiIxESl8sNDg62sLDYuXMn3lkAUHGtKFtSnp6eU6dOVUAYooqOjh4xYsS6desmTpyIdxYAVF9TF0A0obKy0sDAICkpyc3NTQGpiGTv3r35+fl79uzBOwgA6uJLjrYQQgYGBtiFXatXr5Z3JMKora2dMmWKqakp1CwAlEn2dxJbqF+/fjwer6qqikKhaGtryy8VAcTExPz0009hYWGurq54ZwFAvXzhSWJ9Eonk+fPnpaWlo0ePllOq9u7AgQMZGRnwtU0AcPGFJ4n1kUikXr16xcfHZ2ZmyiNSu1ZXVzd9+nR9fX2oWQDgRQ5HW1IsFksoFAoEAisrK3kts1159uxZSEhIWFgYfBABAI7a1NtqgMlkikSib775ZteuXap3veWhQ4dSU1NjYmLwDgKAupPDSWJ9ZDL5+vXrJSUl8l0svoRC4axZs7S1tQ8cOIB3FgCAvMsWpk+fPgihiRMnqsB3sF++fNm3b9/vv/9+xowZeGcBACBFlS3M3r17w8LCGkwcMWKE4tbYRk+fPh0wYED9KUeOHDl9+vTz58+7du2KXy4AwL8osGyZm5uvWLECIXT27Flsiq+vb0lJSbu9OPP8+fNVVVVY5ZJIJHPmzKFSqYcOHcI7FwDgX+TZkm+Mo6PjggULUlNTxWIx9g2+SZMmmZubK2HVLffixYv09HQSiVRdXT148OCKioqwsLBu3brhnQsA0JACj7akevXqlZOTU11djf1YUFBw/vx5Jay3Vc6dO1dRUYE9ZrFYr169gpoFQPukjLKFECotLa3/Y1RUVFlZmXJW3RIvXrxIS0uT/kgikbp3745rIgBAo5RRtnr37t3gotaioqJLly4pYdUtdPbs2QZlVCKR9O7dG79EAIBGKaNs+fj42NjYGBkZaWtrSyQSsVgsEokiIiIaHILh5dWrV9nZ2QghsVgskUi0tbWZTGbHjh179uyJdzQAgAzy/HJPY6orhHmpNXkZleWlNZwqQS2PJ+IjkVhkaWmp6FW3RFlZWV1dHYVCodAEWjRdPUMa01Tb2knfzk2HSlfSSTQAoOUUW7Zio9iJz9g8rtjAQo+koUGhkSlUMpmsIUEKr5VfgkQSCcTCOqGQLxLWCSoKOcYd6B59GS7eengnAwB8pqiyFRtV+fQWy8LZiK5Pp+tRFbEKJeBW8HjsmuqPNX1HGzt21cE7DgAAKaRs8WrEt46XiMRkEwcjDTJJvgvHBb9G+DGLxTAij5xlhncWAIC8y1ZhVu2No4WOvTpq0slyXGx7wCnnlaSVTl1to0mDhhcAeJJn2WKzBNcOF9l5t4tGuyIIeKLCpOJJKzpq0lThKBIAgpLbgUNZIf9Pla5ZCCFNOtnayzJsterfxBWA9kxuZevirjxbla5ZGBIJ2ftYnt+Rj3cQANSXfE4S75wsQVoMbX2ifmLYWlXFHFNzUc9hRngHAUAdyeFoKzelprJMpD41CyHEMNeNf1xZyxHhHQQAdSSHshX9Z5mRrdodd5g6MKOvt6NvgwOgPtpatnKSuVQdGl1XU0555Cw2ISJkbQ8Ot0LuSzaw0P34QcBlwwEXAMrW1rKVEcfV1KbJKQzBkGma2ckcvFMAoHbaWrayk7gME205hSEYXSPtjFgu3ikAUDttuikzq5BvaK5FoSnqgvicvPj7D4/lFyTr6hi6duo7eMBsOl0HIRTz/MqDqBMLZh45czG0pDSrg5ljv94Tfby+xl516+6B13F3aFTtbl2GmBpbKygbQkjPRLv4Y5Xilg8AkKlNR1sctrCuVlHNnTJW/m+nFgsEdd/NPTZt0i9FJe+PnFggEgkRQmSKZm1t9fXbu4LGrNq56XkX94GXr2+pqCxGCD19efXpy/DAESt+mHeSaWjx4OFxBcXDVLHq4PNEAJSsrWWLrKmoQTText2lkDWnT/zFzMTW3NT+29GrPxSlJaZEYXNFIsGgAbNtOnqQSCRvzxESieRDUTpC6Mmzy13c/Lu4D9TWZvh4fe1o762geBiqFoXLFip0FQCABtpUtvg1IgpdUZ8h5uTFd7TqrKNjgP1oZNiBaWSVnRsrfYK1pRv2QFuLgRCq5VVLJJKy8nwzUzvpc6wsXBQU79Oq9Wk11XC0BYBStelYiUQmCfkC+YX5l1oeJ/9DcsjaHvUnVlWzPq+d1PD7zLw6rlgsotE+f0RApWopKN6nNXIEFCrcEAIApWpT2dJhUMSCWvmF+Rc9PaadjeeQgXP/tUYd/SZeQqfpaGiQBQKedEodv0ZB8TCCOqEOQ9Vu0QNAO9emsqXNIAv5ijpFsjBzehN3x962m4bGp8OZ4tIsE2ZTnwySSCRDgw45eQl+fT5NSUmLUVA8TF2tSJuhjCFyAQBSbTrBYXagifhi+YX5l369J4rF4pt/7+XzeaUfc2/dO7j74KSikoymX9XVPSAh+WFsQgRC6J/HZ3ILEhUUDyEk4An1jamaVLj3FgBK1aayRdfW0NbTqKmsk1+ez7S1GSHfXaBqau07+r/27ia0aTCMA3japGm6j7Slutau2q10imLn12GwKXMoih7cRPQyZYggCB48eHM7ehHmQfCkdw9ePO2keBBBDwpOmE5sp8h06+eSmmbNR+Ohl6LpVJo0zfr/Xd8mfQj0T/om7/NO3bl3IfXl7fmJW3+dYj8+enno0PiTudmbM0MfFl+eOXWjuumhGRXy6VIkzphxZgDYQKONa948K3xeUILxtltKTRDEt3c/xs4FIgPmzvoDwG8afQq282B3xbSHia2sIldctAOZBdB8jU4nd/up4HaqsMz7e1ndDxTWVmbvT+oOedxdYll/KXJoa+z61QcN1lZr+vaxekOqqpCkznXoj+67cvFuvaMyqdzgCPZPBLCAAd1N5bL2cCa1e6xPd1RVFY5P6w5J0jpN688NOZ2Uz9vTYGG18oXv9YYkuUy7dJpYUCTNslt0DykL8srH1anpqIEVAsA/MqYp8/wLbumT6g1v9FLVZpJJZkZOe8Mx/EMEsIAxb3gPHvEytFxMt0XzqWwqN5BgkFkAVjFsYcrJS0GlJHCrm7z/VDqZD0XI/aM+qwsBaF9Grqc7ey0s5jh+pWjgOVtKNpWL9DsPjwesLgSgrRm5K3XV00dpoUSy23x/rHS2MUlUuOVCPMEcOIr7LACLGR9bBEEsvC4+f7waivsDUdv/yCuqll3KCXnxxGSwN475LADrmRJbVa/m8l8XRY0gPb4OtqfD4bTT3ZciqXy6JK4JToeWGO7eO9wuD0kBWp+JsUUQhCJpyfc/k/NCISOXeIX2UC6GpN2Uqpq1ALsRLjcpFiV5XZVEhWbIHbs8sURX35423eADoGWZG1u1BE4ReFXgFbmsaZUmfel/ISmHi3F2slQnS3q60EULoEU1L7YAAAyBhsIAYDOILQCwGcQWANgMYgsAbAaxBQA2g9gCAJv5BaHBEGOXBtNPAAAAAElFTkSuQmCC",
      "text/plain": [
       "<IPython.core.display.Image object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "from IPython.display import Image, display\n",
    "\n",
    "display(Image(graph.get_graph().draw_mermaid_png()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "354a03a8",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Update from node generate_query_or_respond\n",
      "==================================\u001b[1m Ai Message \u001b[0m==================================\n",
      "\n",
      "I'll search for Lilian Weng's blog posts about reward hacking to find what she says about the different types.\n",
      "Tool Calls:\n",
      "  retrieve_blog_posts (call_00_4DZ9pMwLxTcceIJW80PyBNQE)\n",
      " Call ID: call_00_4DZ9pMwLxTcceIJW80PyBNQE\n",
      "  Args:\n",
      "    query: reward hacking types\n",
      "\n",
      "\n",
      "\n",
      "Update from node retrieve\n",
      "=================================\u001b[1m Tool Message \u001b[0m=================================\n",
      "Name: retrieve_blog_posts\n",
      "\n",
      "Why does Reward Hacking Exist?#\n",
      "\n",
      "\n",
      "\n",
      "Update from node rewrite_question\n"
     ]
    },
    {
     "ename": "AttributeError",
     "evalue": "'dict' object has no attribute 'pretty_print'",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mAttributeError\u001b[39m                            Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[30]\u001b[39m\u001b[32m, line 13\u001b[39m\n\u001b[32m     11\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m node, update \u001b[38;5;129;01min\u001b[39;00m chunk.items():\n\u001b[32m     12\u001b[39m     \u001b[38;5;28mprint\u001b[39m(\u001b[33m\"\u001b[39m\u001b[33mUpdate from node\u001b[39m\u001b[33m\"\u001b[39m, node)\n\u001b[32m---> \u001b[39m\u001b[32m13\u001b[39m     \u001b[43mupdate\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mmessages\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m[\u001b[49m\u001b[43m-\u001b[49m\u001b[32;43m1\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m.\u001b[49m\u001b[43mpretty_print\u001b[49m()\n\u001b[32m     14\u001b[39m     \u001b[38;5;28mprint\u001b[39m(\u001b[33m\"\u001b[39m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[38;5;130;01m\\n\u001b[39;00m\u001b[33m\"\u001b[39m)\n",
      "\u001b[31mAttributeError\u001b[39m: 'dict' object has no attribute 'pretty_print'"
     ]
    }
   ],
   "source": [
    "for chunk in graph.stream(\n",
    "    {\n",
    "        \"messages\": [\n",
    "            {\n",
    "                \"role\": \"user\",\n",
    "                \"content\": \"What does Lilian Weng say about types of reward hacking?\",\n",
    "            }\n",
    "        ]\n",
    "    }\n",
    "):\n",
    "    for node, update in chunk.items():\n",
    "        print(\"Update from node\", node)\n",
    "        update[\"messages\"][-1].pretty_print()\n",
    "        print(\"\\n\\n\")"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".venv",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
